authentication-setup

安装量: 10.4K
排名: #226

安装

npx skills add https://github.com/supercent-io/skills-template --skill authentication-setup
Authentication Setup
When to use this skill
Lists specific situations where this skill should be triggered:
User Login System
When adding user authentication to a new application
API Security
When adding an authentication layer to a REST or GraphQL API
Permission Management
When role-based access control is needed
Authentication Migration
When migrating an existing auth system to JWT or OAuth
SSO Integration
When integrating social login with Google, GitHub, Microsoft, etc.
Input Format
The required and optional input information to collect from the user:
Required Information
Authentication Method
Choose from JWT, Session, or OAuth 2.0
Backend Framework
Express, Django, FastAPI, Spring Boot, etc.
Database
PostgreSQL, MySQL, MongoDB, etc.
Security Requirements
Password policy, token expiry times, etc.
Optional Information
MFA Support
Whether to enable 2FA/MFA (default: false)
Social Login
OAuth providers (Google, GitHub, etc.)
Session Storage
Redis, in-memory, etc. (if using sessions)
Refresh Token
Whether to use (default: true) Input Example Build a user authentication system: - Auth method: JWT - Framework: Express.js + TypeScript - Database: PostgreSQL - MFA: Google Authenticator support - Social login: Google, GitHub - Refresh Token: enabled Instructions Specifies the step-by-step task sequence to follow precisely. Step 1: Design the Data Model Design the database schema for users and authentication. Tasks : Design the User table (id, email, password_hash, role, created_at, updated_at) RefreshToken table (optional) OAuthProvider table (if using social login) Never store passwords in plaintext (bcrypt/argon2 hashing is mandatory) Example (PostgreSQL): CREATE TABLE users ( id UUID PRIMARY KEY DEFAULT gen_random_uuid ( ) , email VARCHAR ( 255 ) UNIQUE NOT NULL , password_hash VARCHAR ( 255 ) , -- NULL if OAuth only role VARCHAR ( 50 ) DEFAULT 'user' , is_verified BOOLEAN DEFAULT false , mfa_secret VARCHAR ( 255 ) , created_at TIMESTAMP DEFAULT NOW ( ) , updated_at TIMESTAMP DEFAULT NOW ( ) ) ; CREATE TABLE refresh_tokens ( id UUID PRIMARY KEY DEFAULT gen_random_uuid ( ) , user_id UUID REFERENCES users ( id ) ON DELETE CASCADE , token VARCHAR ( 500 ) UNIQUE NOT NULL , expires_at TIMESTAMP NOT NULL , created_at TIMESTAMP DEFAULT NOW ( ) ) ; CREATE INDEX idx_users_email ON users ( email ) ; CREATE INDEX idx_refresh_tokens_user_id ON refresh_tokens ( user_id ) ; Step 2: Implement Password Security Implement password hashing and verification logic. Tasks : Use bcrypt (Node.js) or argon2 (Python) Set salt rounds to a minimum of 10 Password strength validation (minimum 8 chars, upper/lowercase, numbers, special characters) Decision Criteria : Node.js projects → use the bcrypt library Python projects → use argon2-cffi or passlib Performance-critical cases → choose bcrypt Cases requiring maximum security → choose argon2 Example (Node.js + TypeScript): import bcrypt from 'bcrypt' ; const SALT_ROUNDS = 12 ; export async function hashPassword ( password : string ) : Promise < string

{ // Validate password strength if ( password . length < 8 ) { throw new Error ( 'Password must be at least 8 characters' ) ; } const hasUpperCase = / [ A - Z ] / . test ( password ) ; const hasLowerCase = / [ a - z ] / . test ( password ) ; const hasNumber = / \d / . test ( password ) ; const hasSpecial = / [ !@#$%^&*(),.?":{}|<> ] / . test ( password ) ; if ( ! hasUpperCase || ! hasLowerCase || ! hasNumber || ! hasSpecial ) { throw new Error ( 'Password must contain uppercase, lowercase, number, and special character' ) ; } return await bcrypt . hash ( password , SALT_ROUNDS ) ; } export async function verifyPassword ( password : string , hash : string ) : Promise < boolean

{ return await bcrypt . compare ( password , hash ) ; } Step 3: Generate and Verify JWT Tokens Implement a token system for JWT-based authentication. Tasks : Access Token (short expiry: 15 minutes) Refresh Token (long expiry: 7–30 days) Use a strong SECRET key for JWT signing (manage via environment variables) Include only the minimum necessary information in the token payload (user_id, role) Example (Node.js): import jwt from 'jsonwebtoken' ; const ACCESS_TOKEN_SECRET = process . env . ACCESS_TOKEN_SECRET ! ; const REFRESH_TOKEN_SECRET = process . env . REFRESH_TOKEN_SECRET ! ; const ACCESS_TOKEN_EXPIRY = '15m' ; const REFRESH_TOKEN_EXPIRY = '7d' ; interface TokenPayload { userId : string ; email : string ; role : string ; } export function generateAccessToken ( payload : TokenPayload ) : string { return jwt . sign ( payload , ACCESS_TOKEN_SECRET , { expiresIn : ACCESS_TOKEN_EXPIRY , issuer : 'your-app-name' , audience : 'your-app-users' } ) ; } export function generateRefreshToken ( payload : TokenPayload ) : string { return jwt . sign ( payload , REFRESH_TOKEN_SECRET , { expiresIn : REFRESH_TOKEN_EXPIRY , issuer : 'your-app-name' , audience : 'your-app-users' } ) ; } export function verifyAccessToken ( token : string ) : TokenPayload { return jwt . verify ( token , ACCESS_TOKEN_SECRET , { issuer : 'your-app-name' , audience : 'your-app-users' } ) as TokenPayload ; } export function verifyRefreshToken ( token : string ) : TokenPayload { return jwt . verify ( token , REFRESH_TOKEN_SECRET , { issuer : 'your-app-name' , audience : 'your-app-users' } ) as TokenPayload ; } Step 4: Implement Authentication Middleware Write authentication middleware to protect API requests. Checklist : Extract Bearer token from the Authorization header Verify token and check expiry Attach user info to req.user for valid tokens Error handling (401 Unauthorized) Example (Express.js): import { Request , Response , NextFunction } from 'express' ; import { verifyAccessToken } from './jwt' ; export interface AuthRequest extends Request { user ? : { userId : string ; email : string ; role : string ; } ; } export function authenticateToken ( req : AuthRequest , res : Response , next : NextFunction ) { const authHeader = req . headers [ 'authorization' ] ; const token = authHeader && authHeader . split ( ' ' ) [ 1 ] ; // Bearer TOKEN if ( ! token ) { return res . status ( 401 ) . json ( { error : 'Access token required' } ) ; } try { const payload = verifyAccessToken ( token ) ; req . user = payload ; next ( ) ; } catch ( error ) { if ( error . name === 'TokenExpiredError' ) { return res . status ( 401 ) . json ( { error : 'Token expired' } ) ; } return res . status ( 403 ) . json ( { error : 'Invalid token' } ) ; } } // Role-based authorization middleware export function requireRole ( ... roles : string [ ] ) { return ( req : AuthRequest , res : Response , next : NextFunction ) => { if ( ! req . user ) { return res . status ( 401 ) . json ( { error : 'Authentication required' } ) ; } if ( ! roles . includes ( req . user . role ) ) { return res . status ( 403 ) . json ( { error : 'Insufficient permissions' } ) ; } next ( ) ; } ; } Step 5: Implement Authentication API Endpoints Write APIs for registration, login, token refresh, etc. Tasks : POST /auth/register - registration POST /auth/login - login POST /auth/refresh - token refresh POST /auth/logout - logout GET /auth/me - current user info Example : import express from 'express' ; import { hashPassword , verifyPassword } from './password' ; import { generateAccessToken , generateRefreshToken , verifyRefreshToken } from './jwt' ; import { authenticateToken } from './middleware' ; const router = express . Router ( ) ; // Registration router . post ( '/register' , async ( req , res ) => { try { const { email , password } = req . body ; // Check for duplicate email const existingUser = await db . user . findUnique ( { where : { email } } ) ; if ( existingUser ) { return res . status ( 409 ) . json ( { error : 'Email already exists' } ) ; } // Hash the password const passwordHash = await hashPassword ( password ) ; // Create the user const user = await db . user . create ( { data : { email , password_hash : passwordHash , role : 'user' } } ) ; // Generate tokens const accessToken = generateAccessToken ( { userId : user . id , email : user . email , role : user . role } ) ; const refreshToken = generateRefreshToken ( { userId : user . id , email : user . email , role : user . role } ) ; // Store Refresh token in DB await db . refreshToken . create ( { data : { user_id : user . id , token : refreshToken , expires_at : new Date ( Date . now ( ) + 7 * 24 * 60 * 60 * 1000 ) // 7 days } } ) ; res . status ( 201 ) . json ( { user : { id : user . id , email : user . email , role : user . role } , accessToken , refreshToken } ) ; } catch ( error ) { res . status ( 500 ) . json ( { error : error . message } ) ; } } ) ; // Login router . post ( '/login' , async ( req , res ) => { try { const { email , password } = req . body ; // Find the user const user = await db . user . findUnique ( { where : { email } } ) ; if ( ! user || ! user . password_hash ) { return res . status ( 401 ) . json ( { error : 'Invalid credentials' } ) ; } // Verify the password const isValid = await verifyPassword ( password , user . password_hash ) ; if ( ! isValid ) { return res . status ( 401 ) . json ( { error : 'Invalid credentials' } ) ; } // Generate tokens const accessToken = generateAccessToken ( { userId : user . id , email : user . email , role : user . role } ) ; const refreshToken = generateRefreshToken ( { userId : user . id , email : user . email , role : user . role } ) ; // Store Refresh token await db . refreshToken . create ( { data : { user_id : user . id , token : refreshToken , expires_at : new Date ( Date . now ( ) + 7 * 24 * 60 * 60 * 1000 ) } } ) ; res . json ( { user : { id : user . id , email : user . email , role : user . role } , accessToken , refreshToken } ) ; } catch ( error ) { res . status ( 500 ) . json ( { error : error . message } ) ; } } ) ; // Token refresh router . post ( '/refresh' , async ( req , res ) => { try { const { refreshToken } = req . body ; if ( ! refreshToken ) { return res . status ( 401 ) . json ( { error : 'Refresh token required' } ) ; } // Verify Refresh token const payload = verifyRefreshToken ( refreshToken ) ; // Check token in DB const storedToken = await db . refreshToken . findUnique ( { where : { token : refreshToken } } ) ; if ( ! storedToken || storedToken . expires_at < new Date ( ) ) { return res . status ( 403 ) . json ( { error : 'Invalid or expired refresh token' } ) ; } // Generate new Access token const accessToken = generateAccessToken ( { userId : payload . userId , email : payload . email , role : payload . role } ) ; res . json ( { accessToken } ) ; } catch ( error ) { res . status ( 403 ) . json ( { error : 'Invalid refresh token' } ) ; } } ) ; // Current user info router . get ( '/me' , authenticateToken , async ( req : AuthRequest , res ) => { try { const user = await db . user . findUnique ( { where : { id : req . user ! . userId } , select : { id : true , email : true , role : true , created_at : true } } ) ; res . json ( { user } ) ; } catch ( error ) { res . status ( 500 ) . json ( { error : error . message } ) ; } } ) ; export default router ; Output format Defines the exact format that deliverables should follow. Basic Structure Project directory/ ├── src/ │ ├── auth/ │ │ ├── password.ts # password hashing/verification │ │ ├── jwt.ts # JWT token generation/verification │ │ ├── middleware.ts # authentication middleware │ │ └── routes.ts # authentication API endpoints │ ├── models/ │ │ └── User.ts # user model │ └── database/ │ └── schema.sql # database schema ├── .env.example # environment variable template └── README.md # authentication system documentation Environment Variable File (.env.example)

JWT Secrets (MUST change in production)

ACCESS_TOKEN_SECRET

your-access-token-secret-min-32-characters REFRESH_TOKEN_SECRET = your-refresh-token-secret-min-32-characters

Database

DATABASE_URL

postgresql://user:password@localhost:5432/myapp

OAuth (Optional)

GOOGLE_CLIENT_ID

your-google-client-id
GOOGLE_CLIENT_SECRET
=
your-google-client-secret
GITHUB_CLIENT_ID
=
your-github-client-id
GITHUB_CLIENT_SECRET
=
your-github-client-secret
Constraints
Specifies mandatory rules and prohibited actions.
Mandatory Rules (MUST)
Password Security
Never store passwords in plaintext
Use a proven hashing algorithm such as bcrypt or argon2
Salt rounds minimum of 10
Environment Variable Management
Manage all secret keys via environment variables
Add .env files to .gitignore
Provide a list of required variables via .env.example
Token Expiry
Access Tokens should be short-lived (15 min), Refresh Tokens appropriately longer (7 days)
Balance security and user experience
Store Refresh Tokens in the DB to enable revocation
Prohibited Actions (MUST NOT)
Plaintext Passwords
Never store passwords in plaintext or print them to logs
Serious security risk
Legal liability issues
Hardcoding JWT SECRET
Do not write SECRET keys directly in code
Risk of being exposed on GitHub
Production security vulnerability
Sensitive Data in Tokens
Do not include passwords, card numbers, or other sensitive data in JWT payloads
JWT can be decoded (it is not encrypted)
Include only the minimum information (user_id, role)
Security Rules
Rate Limiting
Apply rate limiting to the login API (prevents brute-force attacks)
HTTPS Required
Use HTTPS only in production environments
CORS Configuration
Allow only approved domains to access the API
Input Validation
Validate all user input (prevents SQL Injection and XSS)
Examples
Demonstrates how to apply the skill through real-world use cases.
Example 1: Express.js + PostgreSQL JWT Authentication
Situation
Adding JWT-based user authentication to a Node.js Express app
User Request
:
Add JWT authentication to an Express.js app using PostgreSQL,
with access token expiry of 15 minutes and refresh token expiry of 7 days.
Skill Application Process
:
Install packages:
npm
install
jsonwebtoken bcrypt pg
npm
install
--save-dev @types/jsonwebtoken @types/bcrypt
Create the database schema (use the SQL above)
Set environment variables:
ACCESS_TOKEN_SECRET
=
$(
openssl rand
-base64
32
)
REFRESH_TOKEN_SECRET
=
$(
openssl rand
-base64
32
)
Implement auth modules (use the code examples above)
Connect API routes:
import
authRoutes
from
'./auth/routes'
;
app
.
use
(
'/api/auth'
,
authRoutes
)
;
Final Result
JWT-based authentication system complete, registration/login/token-refresh APIs working
Example 2: Role-Based Access Control (RBAC)
Situation
A permission system that distinguishes administrators from regular users
User Request
:
Create an API accessible only to administrators.
Regular users should receive a 403 error.
Final Result
:
// Admin-only API
router
.
delete
(
'/users/:id'
,
authenticateToken
,
// verify authentication
requireRole
(
'admin'
)
,
// verify role
async
(
req
,
res
)
=>
{
// user deletion logic
await
db
.
user
.
delete
(
{
where
:
{
id
:
req
.
params
.
id
}
}
)
;
res
.
json
(
{
message
:
'User deleted'
}
)
;
}
)
;
// Usage example
// Regular user (role: 'user') request → 403 Forbidden
// Admin (role: 'admin') request → 200 OK
Best practices
Recommendations for using this skill effectively.
Quality Improvement
Password Rotation Policy
Recommend periodic password changes
Change notification every 90 days
Prevent reuse of the last 5 passwords
Balance user experience and security
Multi-Factor Authentication (MFA)
Apply 2FA to important accounts
Use TOTP apps such as Google Authenticator or Authy
SMS is less secure (risk of SIM swapping)
Provide backup codes
Audit Logging
Log all authentication events
Record login success/failure, IP address, and User Agent
Anomaly detection and post-incident analysis
GDPR compliance (exclude sensitive data)
Efficiency Improvements
Token Blacklist
Revoke Refresh Tokens on logout
Redis Caching
Cache frequently used user data
Database Indexing
Add indexes on email and refresh_token
Common Issues
Common problems and their solutions.
Issue 1: "JsonWebTokenError: invalid signature"
Symptom
:
Error occurs during token verification
Login succeeds but authenticated API calls fail
Cause
:
The SECRET keys for Access Token and Refresh Token are different,
but the same key is being used to verify both.
Solution
:
Check environment variables:
ACCESS_TOKEN_SECRET
,
REFRESH_TOKEN_SECRET
Use the correct SECRET for each token type
Verify that environment variables load correctly (initialize
dotenv
)
Issue 2: Frontend Cannot Log In Due to CORS Error
Symptom
"CORS policy" error in the browser console
Cause
Missing CORS configuration on the Express server
Solution
:
import
cors
from
'cors'
;
app
.
use
(
cors
(
{
origin
:
process
.
env
.
FRONTEND_URL
||
'http://localhost:3000'
,
credentials
:
true
}
)
)
;
Issue 3: Refresh Token Keeps Expiring
Symptom
Users are frequently logged out
Cause
Refresh Token is not properly managed in the DB
Solution
:
Confirm Refresh Token is saved to DB upon creation
Set an appropriate expiry time (minimum 7 days)
Add a cron job to regularly clean up expired tokens
References
Official Documentation
JWT.io - JSON Web Token Introduction
OWASP Authentication Cheat Sheet
OAuth 2.0 RFC 6749
Libraries
jsonwebtoken (Node.js)
bcrypt (Node.js)
Passport.js
- multiple authentication strategies
NextAuth.js
- Next.js authentication
Security Guides
OWASP Top 10
NIST Digital Identity Guidelines
Metadata
Version
Current Version
1.0.0
Last Updated
2025-01-01
Compatible Platforms
Claude, ChatGPT, Gemini
返回排行榜