auth0-authentication
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAuth0 Authentication
Auth0身份验证
You are an expert in Auth0 authentication implementation. Follow these guidelines when working with Auth0 in any project.
您是Auth0身份验证实施方面的专家。在任何项目中使用Auth0时,请遵循以下指南。
Core Principles
核心原则
- Always use HTTPS for all Auth0 communications and callbacks
- Store sensitive configuration (client secrets, API keys) in environment variables, never in code
- Implement proper error handling for all authentication flows
- Follow the principle of least privilege for scopes and permissions
- 所有Auth0通信和回调始终使用HTTPS
- 敏感配置(客户端密钥、API密钥)存储在环境变量中,绝不要写入代码
- 为所有身份验证流程实现适当的错误处理
- 遵循权限最小化原则设置作用域和权限
Environment Variables
环境变量
bash
undefinedbash
undefinedRequired Auth0 Configuration
Required Auth0 Configuration
AUTH0_DOMAIN=your-tenant.auth0.com
AUTH0_CLIENT_ID=your-client-id
AUTH0_CLIENT_SECRET=your-client-secret
AUTH0_AUDIENCE=your-api-audience
AUTH0_CALLBACK_URL=https://your-app.com/callback
AUTH0_LOGOUT_URL=https://your-app.com
undefinedAUTH0_DOMAIN=your-tenant.auth0.com
AUTH0_CLIENT_ID=your-client-id
AUTH0_CLIENT_SECRET=your-client-secret
AUTH0_AUDIENCE=your-api-audience
AUTH0_CALLBACK_URL=https://your-app.com/callback
AUTH0_LOGOUT_URL=https://your-app.com
undefinedAuthentication Flows
身份验证流程
Authorization Code Flow with PKCE (Recommended for SPAs and Native Apps)
带PKCE的授权码流程(推荐用于SPA和原生应用)
Always use PKCE for public clients:
javascript
import { Auth0Client } from '@auth0/auth0-spa-js';
const auth0 = new Auth0Client({
domain: process.env.AUTH0_DOMAIN,
clientId: process.env.AUTH0_CLIENT_ID,
authorizationParams: {
redirect_uri: window.location.origin,
audience: process.env.AUTH0_AUDIENCE,
},
cacheLocation: 'localstorage', // Use 'memory' for higher security
useRefreshTokens: true,
});公共客户端始终使用PKCE:
javascript
import { Auth0Client } from '@auth0/auth0-spa-js';
const auth0 = new Auth0Client({
domain: process.env.AUTH0_DOMAIN,
clientId: process.env.AUTH0_CLIENT_ID,
authorizationParams: {
redirect_uri: window.location.origin,
audience: process.env.AUTH0_AUDIENCE,
},
cacheLocation: 'localstorage', // Use 'memory' for higher security
useRefreshTokens: true,
});Authorization Code Flow (Server-Side Applications)
授权码流程(服务器端应用)
javascript
// Express.js example
const { auth } = require('express-openid-connect');
app.use(
auth({
authRequired: false,
auth0Logout: true,
secret: process.env.AUTH0_SECRET,
baseURL: process.env.BASE_URL,
clientID: process.env.AUTH0_CLIENT_ID,
issuerBaseURL: `https://${process.env.AUTH0_DOMAIN}`,
})
);javascript
// Express.js example
const { auth } = require('express-openid-connect');
app.use(
auth({
authRequired: false,
auth0Logout: true,
secret: process.env.AUTH0_SECRET,
baseURL: process.env.BASE_URL,
clientID: process.env.AUTH0_CLIENT_ID,
issuerBaseURL: `https://${process.env.AUTH0_DOMAIN}`,
})
);Auth0 Actions Best Practices
Auth0 Actions最佳实践
Actions have replaced Rules. Follow these guidelines:
Actions已取代Rules。请遵循以下指南:
Action Structure
Action结构
javascript
exports.onExecutePostLogin = async (event, api) => {
// 1. Early returns for efficiency
if (!event.user.email_verified) {
api.access.deny('Please verify your email before logging in.');
return;
}
// 2. Use secrets for sensitive data (configured in Auth0 Dashboard)
const apiKey = event.secrets.EXTERNAL_API_KEY;
// 3. Minimize external calls - they affect login latency
// 4. Never log sensitive information
console.log(`User logged in: ${event.user.user_id}`);
// 5. Add custom claims sparingly
api.idToken.setCustomClaim('https://myapp.com/roles', event.authorization?.roles || []);
api.accessToken.setCustomClaim('https://myapp.com/roles', event.authorization?.roles || []);
};javascript
exports.onExecutePostLogin = async (event, api) => {
// 1. Early returns for efficiency
if (!event.user.email_verified) {
api.access.deny('Please verify your email before logging in.');
return;
}
// 2. Use secrets for sensitive data (configured in Auth0 Dashboard)
const apiKey = event.secrets.EXTERNAL_API_KEY;
// 3. Minimize external calls - they affect login latency
// 4. Never log sensitive information
console.log(`User logged in: ${event.user.user_id}`);
// 5. Add custom claims sparingly
api.idToken.setCustomClaim('https://myapp.com/roles', event.authorization?.roles || []);
api.accessToken.setCustomClaim('https://myapp.com/roles', event.authorization?.roles || []);
};Action Security Rules
Action安全规则
- Store secrets in Action Secrets, never hardcode them
- Limit the data sent to external services - never send the entire event object
- Use short timeouts for external API calls (default 20-second limit)
- Implement proper error handling to avoid authentication failures
- 敏感数据存储在Action Secrets中,绝不要硬编码
- 限制发送到外部服务的数据——绝不发送完整的event对象
- 为外部API调用设置短超时(默认限制为20秒)
- 实施适当的错误处理,避免身份验证失败
Token Management
Token管理
Access Token Best Practices
Access Token最佳实践
javascript
// Always validate tokens server-side
const { auth, requiredScopes } = require('express-oauth2-jwt-bearer');
const checkJwt = auth({
audience: process.env.AUTH0_AUDIENCE,
issuerBaseURL: `https://${process.env.AUTH0_DOMAIN}/`,
tokenSigningAlg: 'RS256',
});
// Require specific scopes
const checkScopes = requiredScopes('read:messages');
app.get('/api/private-scoped', checkJwt, checkScopes, (req, res) => {
res.json({ message: 'Protected resource' });
});javascript
// Always validate tokens server-side
const { auth, requiredScopes } = require('express-oauth2-jwt-bearer');
const checkJwt = auth({
audience: process.env.AUTH0_AUDIENCE,
issuerBaseURL: `https://${process.env.AUTH0_DOMAIN}/`,
tokenSigningAlg: 'RS256',
});
// Require specific scopes
const checkScopes = requiredScopes('read:messages');
app.get('/api/private-scoped', checkJwt, checkScopes, (req, res) => {
res.json({ message: 'Protected resource' });
});Refresh Token Configuration
Refresh Token配置
- Enable refresh token rotation
- Set appropriate token lifetimes (access tokens: 1 hour max, refresh tokens: based on risk)
- Implement automatic token refresh in your client
- 启用Refresh Token轮换
- 设置合适的Token有效期(Access Token:最长1小时,Refresh Token:根据风险设置)
- 在客户端中实现自动Token刷新
Security Best Practices
安全最佳实践
CSRF Protection
CSRF防护
javascript
// State parameter is automatically handled by Auth0 SDKs
// For custom implementations, always validate the state parameter
const state = generateSecureRandomString();
sessionStorage.setItem('auth0_state', state);javascript
// State parameter is automatically handled by Auth0 SDKs
// For custom implementations, always validate the state parameter
const state = generateSecureRandomString();
sessionStorage.setItem('auth0_state', state);Redirect URI Security
重定向URI安全
- Whitelist all redirect URIs in Auth0 Dashboard
- Use exact string matching for redirect URIs
- Never use wildcard redirect URIs in production
- 在Auth0控制台中白名单所有重定向URI
- 对重定向URI使用精确字符串匹配
- 生产环境中绝不使用通配符重定向URI
Session Management
会话管理
javascript
// Implement session timeouts
const sessionConfig = {
absoluteDuration: 86400, // 24 hours
inactivityDuration: 3600, // 1 hour of inactivity
};javascript
// Implement session timeouts
const sessionConfig = {
absoluteDuration: 86400, // 24 hours
inactivityDuration: 3600, // 1 hour of inactivity
};Multi-Factor Authentication
多因素身份验证(MFA)
javascript
// Enforce MFA for sensitive operations
exports.onExecutePostLogin = async (event, api) => {
// Check if MFA has been completed
if (!event.authentication?.methods?.find(m => m.name === 'mfa')) {
// Trigger MFA challenge
api.authentication.challengeWithAny([
{ type: 'otp' },
{ type: 'push-notification' },
]);
}
};javascript
// Enforce MFA for sensitive operations
exports.onExecutePostLogin = async (event, api) => {
// Check if MFA has been completed
if (!event.authentication?.methods?.find(m => m.name === 'mfa')) {
// Trigger MFA challenge
api.authentication.challengeWithAny([
{ type: 'otp' },
{ type: 'push-notification' },
]);
}
};Error Handling
错误处理
javascript
try {
await auth0.loginWithRedirect();
} catch (error) {
if (error.error === 'access_denied') {
// User denied access or email not verified
handleAccessDenied(error);
} else if (error.error === 'login_required') {
// Session expired
handleSessionExpired();
} else {
// Generic error handling
console.error('Authentication error:', error.message);
showUserFriendlyError();
}
}javascript
try {
await auth0.loginWithRedirect();
} catch (error) {
if (error.error === 'access_denied') {
// User denied access or email not verified
handleAccessDenied(error);
} else if (error.error === 'login_required') {
// Session expired
handleSessionExpired();
} else {
// Generic error handling
console.error('Authentication error:', error.message);
showUserFriendlyError();
}
}MCP Integration
MCP集成
Auth0 provides an MCP server for AI-assisted development:
bash
undefinedAuth0提供MCP服务器用于AI辅助开发:
bash
undefinedInitialize Auth0 MCP server for Cursor
Initialize Auth0 MCP server for Cursor
npx @auth0/auth0-mcp-server init --client cursor
This enables natural language Auth0 management operations within your IDE.npx @auth0/auth0-mcp-server init --client cursor
这允许您在IDE内通过自然语言执行Auth0管理操作。Testing
测试
- Use Auth0's test users for development
- Implement integration tests for authentication flows
- Test token expiration and refresh scenarios
- Verify MFA flows in staging environments
- 使用Auth0的测试用户进行开发
- 为身份验证流程实现集成测试
- 测试Token过期和刷新场景
- 在预发布环境中验证MFA流程
Common Anti-Patterns to Avoid
需避免的常见反模式
- Storing tokens in localStorage without considering XSS risks
- Not validating tokens on the server side
- Using the implicit flow (deprecated)
- Hardcoding client secrets in frontend code
- Not implementing proper logout (both local and Auth0 session)
- Ignoring token expiration in API calls
- Storing too much data in user metadata
- 在localStorage中存储Token却不考虑XSS风险
- 不在服务器端验证Token
- 使用隐式流程(已弃用)
- 在前端代码中硬编码客户端密钥
- 未实现适当的登出(本地和Auth0会话都要处理)
- API调用中忽略Token过期
- 在用户元数据中存储过多数据