Skip to main content

auth-implementation-patterns

Master authentication and authorization patterns including JWT, OAuth2, session management, and RBAC to build secure, scalable access control systems. Use when implementing auth systems, securing APIs, or debugging security issues.

Informações da origem

Repositório
majiayu000/claude-skill-registry-data
Última atividade na origem
21 de abril de 2026 às 02:21
Idioma detectado do SKILL.md
inglês
Estrelas
22
Forks
8

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Explorador de arquivos
2 arquivos

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
auth-implementation-patterns
description
Master authentication and authorization patterns including JWT, OAuth2, session management, and RBAC to build secure, scalable access control systems. Use when implementing auth systems, securing APIs, or debugging security issues.
# Authentication & Authorization Implementation Patterns Build secure, scalable authentication and authorization systems using industry-standard patterns and modern best practices. ## When to Use This Skill - Implementing user authentication systems - Securing REST or GraphQL APIs - Adding OAuth2/social login - Implementing role-based access control (RBAC) - Designing session management - Migrating authentication systems - Debugging auth issues - Implementing SSO or multi-tenancy ## Core Concepts ### 1. Authentication vs Authorization **Authentication (AuthN)**: Who are you? - Verifying identity (username/password, OAuth, biometrics) - Issuing credentials (sessions, tokens) - Managing login/logout **Authorization (AuthZ)**: What can you do? - Permission checking - Role-based access control (RBAC) - Resource ownership validation - Policy enforcement ### 2. Authentication Strategies **Session-Based:** - Server stores session state - Session ID in cookie - Traditional, simple, stateful **Token-Based (JWT):** - Stateless, self-contained - Scales horizontally - Can store claims **OAuth2/OpenID Connect:** - Delegate authentication - Social login (Google, GitHub) - Enterprise SSO ## JWT Authentication ### Pattern 1: JWT Implementation ```typescript // JWT structure: header.payload.signature import jwt from 'jsonwebtoken' import { Request, Response, NextFunction } from 'express' interface JWTPayload { userId: string email: string role: string iat: number exp: number } // Generate JWT function generateTokens(userId: string, email: string, role: string) { const accessToken = jwt.sign( { userId, email, role }, process.env.JWT_SECRET!, { expiresIn: '15m' } // Short-lived ) const refreshToken = jwt.sign( { userId }, process.env.JWT_REFRESH_SECRET!, { expiresIn: '7d' } // Long-lived ) return { accessToken, refreshToken } } // Verify JWT function verifyToken(token: string): JWTPayload { try { return jwt.verify(token, process.env.JWT_SECRET!) as JWTPayload } catch (error) { if (error instanceof jwt.TokenExpiredError) { throw new Error('Token expired') } if (error instanceof jwt.JsonWebTokenError) { throw new Error('Invalid token') } throw error } } // Middleware function authenticate(req: Request, res: Response, next: NextFunction) { const authHeader = req.headers.authorization if (!authHeader?.startsWith('Bearer ')) { return res.status(401).json({ error: 'No token provided' }) } const token = authHeader.substring(7) try { const payload = verifyToken(token) req.user = payload // Attach user to request next() } catch (error) { return res.status(401).json({ error: 'Invalid token' }) } } // Usage app.get('/api/profile', authenticate, (req, res) => { res.json({ user: req.user }) }) ``` ### Pattern 2: Refresh Token Flow ```typescript interface StoredRefreshToken { token: string userId: string expiresAt: Date createdAt: Date } class RefreshTokenService { // Store refresh token in database async storeRefreshToken(userId: string, refreshToken: string) { const expiresAt = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000) await db.refreshTokens.create({ token: await hash(refreshToken), // Hash before storing userId, expiresAt, }) } // Refresh access token async refreshAccessToken(refreshToken: string) { // Verify refresh token let payload try { payload = jwt.verify(refreshToken, process.env.JWT_REFRESH_SECRET!) as { userId: string } } catch { throw new Error('Invalid refresh token') } // Check if token exists in database const storedToken = await db.refreshTokens.findOne({ where: { token: await hash(refreshToken), userId: payload.userId, expiresAt: { $gt: new Date() }, }, }) if (!storedToken) { throw new Error('Refresh token not found or expired') } // Get user const user = await db.users.findById(payload.userId) if (!user) { throw new Error('User not found') } // Generate new access token const accessToken = jwt.sign({ userId: user.id, email: user.email, role: user.role }, process.env.JWT_SECRET!, { expiresIn: '15m', }) return { accessToken } } // Revoke refresh token (logout) async revokeRefreshToken(refreshToken: string) { await db.refreshTokens.deleteOne({ token: await hash(refreshToken), }) } // Revoke all user tokens (logout all devices) async revokeAllUserTokens(userId: string) { await db.refreshTokens.deleteMany({ userId }) } } // API endpoints app.post('/api/auth/refresh', async (req, res) => { const { refreshToken } = req.body try { const { accessToken } = await refreshTokenService.refreshAccessToken(refreshToken) res.json({ accessToken }) } catch (error) { res.status(401).json({ error: 'Invalid refresh token' }) } }) app.post('/api/auth/logout', authenticate, async (req, res) => { const { refreshToken } = req.body await refreshTokenService.revokeRefreshToken(refreshToken) res.json({ message: 'Logged out successfully' }) }) ``` ## Session-Based Authentication ### Pattern 1: Express Session ```typescript import session from 'express-session' import RedisStore from 'connect-redis' import { createClient } from 'redis' // Setup Redis for session storage const redisClient = createClient({ url: process.env.REDIS_URL, }) await redisClient.connect() app.use( session({ store: new RedisStore({ client: redisClient }), secret: process.env.SESSION_SECRET!, resave: false, saveUninitialized: false, cookie: { secure: process.env.NODE_ENV === 'production', // HTTPS only httpOnly: true, // No JavaScript access maxAge: 24 * 60 * 60 * 1000, // 24 hours sameSite: 'strict', // CSRF protection }, }) ) // Login app.post('/api/auth/login', async (req, res) => { const { email, password } = req.body const user = await db.users.findOne({ email }) if (!user || !(await verifyPassword(password, user.passwordHash))) { return res.status(401).json({ error: 'Invalid credentials' }) } // Store user in session req.session.userId = user.id req.session.role = user.role res.json({ user: { id: user.id, email: user.email, role: user.role } }) }) // Session middleware function requireAuth(req: Request, res: Response, next: NextFunction) { if (!req.session.userId) { return res.status(401).json({ error: 'Not authenticated' }) } next() } // Protected route app.get('/api/profile', requireAuth, async (req, res) => { const user = await db.users.findById(req.session.userId) res.json({ user }) }) // Logout app.post('/api/auth/logout', (req, res) => { req.session.destroy((err) => { if (err) { return res.status(500).json({ error: 'Logout failed' }) } res.clearCookie('connect.sid') res.json({ message: 'Logged out successfully' }) }) }) ``` ## OAuth2 / Social Login ### Pattern 1: OAuth2 with Passport.js ```typescript import passport from 'passport' import { Strategy as GoogleStrategy } from 'passport-google-oauth20' import { Strategy as GitHubStrategy } from 'passport-github2' // Google OAuth passport.use( new GoogleStrategy( { clientID: process.env.GOOGLE_CLIENT_ID!, clientSecret: process.env.GOOGLE_CLIENT_SECRET!, callbackURL: '/api/auth/google/callback', }, async (accessToken, refreshToken, profile, done) => { try { // Find or create user let user = await db.users.findOne({ googleId: profile.id, }) if (!user) { user = await db.users.create({ googleId: profile.id, email: profile.emails?.[0]?.value, name: profile.displayName, avatar: profile.photos?.[0]?.value, }) } return done(null, user) } catch (error) { return done(error, undefined) } } ) ) // Routes app.get( '/api/auth/google', passport.authenticate('google', { scope: ['profile', 'email'], }) ) app.get('/api/auth/google/callback', passport.authenticate('google', { session: false }), (req, res) => { // Generate JWT const tokens = generateTokens(req.user.id, req.user.email, req.user.role) // Redirect to frontend with token res.redirect(`${process.env.FRONTEND_URL}/auth/callback?token=${tokens.accessToken}`) }) ``` ## Authorization Patterns ### Pattern 1: Role-Based Access Control (RBAC) ```typescript enum Role { USER = 'user', MODERATOR = 'moderator', ADMIN = 'admin', } const roleHierarchy: Record<Role, Role[]> = { [Role.ADMIN]: [Role.ADMIN, Role.MODERATOR, Role.USER], [Role.MODERATOR]: [Role.MODERATOR, Role.USER], [Role.USER]: [Role.USER], } function hasRole(userRole: Role, requiredRole: Role): boolean { return roleHierarchy[userRole].includes(requiredRole) } // Middleware function requireRole(...roles: Role[]) { return (req: Request, res: Response, next: NextFunction) => { if (!req.user) { return res.status(401).json({ error: 'Not authenticated' }) } if (!roles.some((role) => hasRole(req.user.role, role))) { return res.status(403).json({ error: 'Insufficient permissions' }) } next() } } // Usage app.delete('/api/users/:id', authenticate, requireRole(Role.ADMIN), async (req, res) => { // Only admins can delete users await db.users.delete(req.params.id) res.json({ message: 'User deleted' }) }) ``` ### Pattern 2: Permission-Based Access Control ```typescript enum Permission { READ_USERS = 'read:users', WRITE_USERS = 'write:users', DELETE_USERS = 'delete:users', READ_POSTS = 'read:posts', WRITE_POSTS = 'write:posts', } const rolePermissions: Record<Role, Permission[]> = { [Role.USER]: [Permission.READ_POSTS, Permission.WRITE_POSTS], [Role.MODERATOR]: [Permission.READ_POSTS, Permission.WRITE_POSTS, Permission.READ_USERS], [Role.ADMIN]: Object.values(Permission), } function hasPermission(userRole: Role, permission: Permission): boolean { return rolePermissions[userRole]?.includes(permission) ?? false } function requirePermission(...permissions: Permission[]) { return (req: Request, res: Response, next: NextFunction) => { if (!req.user) { return res.status(401).json({ error: 'Not authenticated' }) } const hasAllPermissions = permissions.every((permission) => hasPermission(req.user.role, permission)) if (!hasAllPermissions) { return res.status(403).json({ error: 'Insufficient permissions' }) } next() } } // Usage app.get('/api/users', authenticate, requirePermission(Permission.READ_USERS), async (req, res) => { const users = await db.users.findAll() res.json({ users }) }) ``` ### Pattern 3: Resource Ownership ```typescript // Check if user owns resource async function requireOwnership(resourceType: 'post' | 'comment', resourceIdParam: string = 'id') { return async (req: Request, res: Response, next: NextFunction) => { if (!req.user) { return res.status(401).json({ error: 'Not authenticated' }) }
Ver no GitHub
Este SKILL.md e muito grande, entao o SkillsMP mostra aqui apenas a primeira secao. Ver no GitHub