askill
auth-patterns

auth-patternsSafety --Repository

Authentication and authorization patterns including JWT vs sessions, OAuth flows, token refresh, RBAC, and password handling. Use when implementing login, signup, token management, role-based access, or reviewing auth security.

1 stars
1.2k downloads
Updated 2/6/2026

Package Files

Loading files...
SKILL.md

Auth Patterns

Decision Tree

Need authentication → What type?
    ├─ Server-rendered app (SSR) → Session-based auth (cookies)
    ├─ SPA / mobile app → JWT (access + refresh tokens)
    ├─ Third-party login (Google, GitHub) → OAuth 2.0 / OIDC
    ├─ Machine-to-machine → API keys or client credentials
    └─ Internal microservice → mTLS or service tokens

JWT vs Sessions

FactorJWTSessions
StorageClient-side (memory or cookie)Server-side (DB/Redis)
ScalabilityStateless, no server lookupRequires shared session store
RevocationHard (need blocklist)Easy (delete from store)
SizeLarger (payload in token)Small (just session ID)
Best forAPIs, SPAs, mobileServer-rendered apps, simple auth

Token Architecture

Login → Issue access token (short-lived: 15min) + refresh token (long-lived: 7-30 days)

API request → Send access token in Authorization header
    ├─ Valid → Process request
    ├─ Expired → Client uses refresh token to get new access token
    └─ Refresh expired → User must re-authenticate

Access token: Short-lived (15 min), contains user ID + roles, sent in Authorization: Bearer <token> header.

Refresh token: Long-lived (7-30 days), stored securely (httpOnly cookie or secure storage), used ONLY to get new access tokens, rotated on use.

Password Handling

NEVER: MD5, SHA1, SHA256 for passwords (fast hash = easy to brute force)
NEVER: Store plaintext passwords
ALWAYS: bcrypt (cost factor 12+) or argon2id
ALWAYS: Salt automatically (bcrypt does this)
import bcrypt from 'bcrypt';
const hash = await bcrypt.hash(password, 12);
const valid = await bcrypt.compare(password, hash);
from passlib.hash import bcrypt
hash = bcrypt.hash(password, rounds=12)
valid = bcrypt.verify(password, hash)

RBAC (Role-Based Access Control)

User → has Roles → Roles have Permissions → Check permission on action

// Middleware pattern
function requirePermission(permission: string) {
  return (req, res, next) => {
    if (!req.user.permissions.includes(permission)) {
      return res.status(403).json({ error: { code: 'FORBIDDEN' } });
    }
    next();
  };
}

app.delete('/users/:id', requirePermission('users:delete'), deleteUser);

Rules:

  • Check permissions server-side ALWAYS (client checks are UX only)
  • Use specific permissions (users:delete) not broad roles (admin) in code
  • Roles map to permission sets in config, not hardcoded
  • No IDOR — verify the user owns the resource, not just that they're authenticated

Security Checklist

  • Passwords hashed with bcrypt (cost 12+) or argon2id
  • Access tokens short-lived (15 min max)
  • Refresh tokens rotated on use
  • Tokens in httpOnly cookies (not localStorage)
  • CSRF protection on cookie-based auth
  • Rate limiting on login/signup endpoints
  • Account lockout after failed attempts
  • No sensitive data in JWT payload (no passwords, secrets)
  • HTTPS everywhere (no auth over HTTP)
  • Logout invalidates refresh token server-side

Anti-Patterns

Anti-PatternFix
JWT in localStoragehttpOnly cookie (XSS-proof)
No token expirationAccess: 15min, Refresh: 7-30 days
Same secret for all tokensSeparate secrets for access/refresh
Permissions checked client-side onlyAlways enforce server-side
Rolling your own cryptoUse bcrypt/argon2id, established JWT libs
No rate limiting on auth endpointsRate limit + account lockout
Refresh tokens that never rotateRotate on every use, detect reuse
Storing user roles in JWT without server checkJWT roles for UX, server check for auth

For OAuth flow details see:

Install

Download ZIP
Requires askill CLI v1.0+

AI Quality Score

AI review pending.

Metadata

Licenseunknown
Version-
Updated2/6/2026
PublisherBigPapiCB

Tags

apigithubsecurity
auth-patterns - AI Agent Skill | askill