认证系统接入指南
完整的 Athena 认证系统使用指南,包含 OAuth 配置、API 使用、安全最佳实践和代码示例
🚀 快速开始
1
配置 OAuth
设置 GitHub、Google 等 OAuth 应用
2
集成 API
使用认证 API 和中间件
3
部署上线
配置生产环境和安全设置
📋 系统概述
认证架构
Athena 采用基于 JWT 的无状态认证系统,支持多种 OAuth 提供商,提供完整的会话管理和安全控制。
核心特性
🔐 多提供商支持
- • GitHub OAuth
- • Google OAuth
- • Microsoft OAuth
- • Gitee OAuth
🛡️ 安全特性
- • JWT 令牌认证
- • 会话管理
- • CSRF 保护
- • 安全 Cookie
⚡ 开发体验
- • 类型安全
- • 中间件支持
- • 简单集成
- • 完整文档
📊 管理功能
- • 用户信息管理
- • 会话监控
- • 设备管理
- • 安全日志
认证流程
1
用户点击登录
→
2
重定向到 OAuth
→
3
授权回调
→
4
生成 JWT
→
5
设置 Cookie
⚙️ OAuth 配置
GitHub OAuth 配置
1. 创建 GitHub OAuth 应用
- 访问 GitHub Developer Settings
- 点击 "New OAuth App"
- 填写应用信息:
- Application name: 你的应用名称
- Homepage URL:
https://yourdomain.com
- Authorization callback URL:
https://yourdomain.com/api/auth/callback?provider=github
- 获取 Client ID 和 Client Secret
2. 环境变量配置
# GitHub OAuth 配置 GITHUB_CLIENT_ID=your_github_client_id GITHUB_CLIENT_SECRET=your_github_client_secret # 基础配置 BASE_URL=https://yourdomain.com JWT_SECRET=your_jwt_secret_key SESSION_EXPIRE_TIME=86400
G
Google OAuth 配置
1. 创建 Google OAuth 应用
- 访问 Google Cloud Console
- 创建新项目或选择现有项目
- 启用 Google+ API
- 创建 OAuth 2.0 客户端 ID
- 配置授权重定向 URI:
https://yourdomain.com/api/auth/callback?provider=google
2. 环境变量配置
# Google OAuth 配置 GOOGLE_CLIENT_ID=your_google_client_id GOOGLE_CLIENT_SECRET=your_google_client_secret
🔌 API 参考
认证端点
GET
/api/auth/[provider]
启动 OAuth 登录流程
支持的提供商
githubgooglemicrosoftgitee
查询参数
参数 | 类型 | 说明 |
---|---|---|
redirect | string | 登录成功后的重定向URL(可选) |
示例
// 基础登录 GET /api/auth/github // 带重定向的登录 GET /api/auth/github?redirect=/dashboard // JavaScript 中使用 window.location.href = '/api/auth/github?redirect=' + encodeURIComponent(window.location.pathname);
GET
/api/auth/me
获取当前登录用户信息
请求头
Cookie: auth_token=your_jwt_token # 或者 Authorization: Bearer your_jwt_token
响应示例
{ "authenticated": true, "user": { "id": "123456", "username": "johndoe", "name": "John Doe", "email": "john@example.com", "avatar": "https://avatars.githubusercontent.com/u/123456", "profileUrl": "https://github.com/johndoe", "provider": "github", "joinedAt": "2024-01-01T00:00:00.000Z", "lastLoginAt": "2024-12-22T10:30:00.000Z" }, "expiresAt": "2024-12-23T10:30:00.000Z" }
GET
/api/auth/sessions
获取用户的所有活跃会话
响应示例
{ "sessions": [ { "id": "session_123", "deviceInfo": { "browser": "Chrome", "os": "macOS", "device": "Desktop" }, "ipAddress": "192.168.1.100", "location": "北京, 中国", "createdAt": "2024-12-22T10:30:00.000Z", "lastActiveAt": "2024-12-22T15:45:00.000Z", "isCurrent": true } ], "stats": { "totalSessions": 3, "activeSessions": 2, "expiredSessions": 1 } }
🛡️ 中间件使用
路由保护
使用认证中间件保护需要登录的路由
// routes/protected-page.tsx import { FreshContext } from "fresh"; import { getAuthContext } from "@utils/middleware.ts"; import type { AppUser } from "@utils/auth.ts"; interface ProtectedPageProps { user: AppUser; } export const handler = { async GET(ctx: FreshContext): Promise<Response> { const req = ctx.req; const authContext = await getAuthContext(req); if (!authContext.isAuthenticated) { // 未登录,重定向到登录页面 const loginUrl = `/api/auth/github?redirect=${ encodeURIComponent(req.url) }`; return new Response(null, { status: 302, headers: { "Location": loginUrl }, }); } return new Response(null, { status: 200 }); }, }; export default function ProtectedPage({ data }: PageProps<ProtectedPageProps>) { return ( <div> <h1>欢迎, {data.user.name}!</h1> <p>这是一个受保护的页面</p> </div> ); }
API 路由保护
// routes/api/protected-endpoint.ts import { FreshContext } from "fresh"; import { getAuthContext } from "@utils/middleware.ts"; export const handler = { async GET(ctx: FreshContext): Promise<Response> { const req = ctx.req; const authContext = await getAuthContext(req); if (!authContext.isAuthenticated) { return new Response( JSON.stringify({ error: "Authentication required" }), { status: 401, headers: { "Content-Type": "application/json" } } ); } // 处理已认证的请求 return new Response( JSON.stringify({ message: "Hello, " + authContext.user?.name, data: "sensitive data" }), { status: 200, headers: { "Content-Type": "application/json" } } ); }, };
🔒 安全最佳实践
JWT 令牌安全
✅ 推荐做法
- • 使用强随机密钥(至少256位)
- • 设置合理的过期时间(24小时内)
- • 使用 HttpOnly Cookie 存储
- • 启用 SameSite 保护
- • 定期轮换密钥
❌ 避免做法
- • 在 localStorage 中存储令牌
- • 使用弱密钥或默认密钥
- • 设置过长的过期时间
- • 在 URL 中传递令牌
- • 忽略令牌验证
环境变量配置
# 生成强随机密钥 JWT_SECRET=$(openssl rand -base64 32) # 设置合理的过期时间(秒) SESSION_EXPIRE_TIME=86400 # 24小时 # 启用安全Cookie设置 SECURE_COOKIES=true SAMESITE_STRICT=true
HTTPS 和 Cookie 安全
Cookie 安全配置
// 安全的 Cookie 设置 const secureCookie = [ "auth_token=jwt_token_here", "HttpOnly", // 防止 XSS 攻击 "Secure", // 仅在 HTTPS 下传输 "SameSite=Strict", // 防止 CSRF 攻击 "Max-Age=86400", // 24小时过期 "Path=/", // 全站有效 ].join("; ");
重要提醒
生产环境必须使用 HTTPS。在开发环境中,Secure 标志会阻止 Cookie 在 HTTP 下工作。
常见攻击防护
CSRF 防护
- • 使用 SameSite Cookie 属性
- • 验证 Referer 头
- • 实施 CSRF 令牌
- • 双重提交 Cookie
XSS 防护
- • 使用 HttpOnly Cookie
- • 输入验证和转义
- • 内容安全策略 (CSP)
- • 避免 innerHTML 使用
会话劫持防护
- • 强制 HTTPS 传输
- • 定期轮换会话ID
- • 监控异常登录
- • 实施会话超时
暴力破解防护
- • 实施速率限制
- • 账户锁定机制
- • 验证码保护
- • 监控失败尝试
🚀 部署指南
环境变量配置
必需的环境变量
# 基础配置 BASE_URL=https://yourdomain.com JWT_SECRET=your_super_secret_jwt_key_here SESSION_EXPIRE_TIME=86400 # GitHub OAuth GITHUB_CLIENT_ID=your_github_client_id GITHUB_CLIENT_SECRET=your_github_client_secret # Google OAuth GOOGLE_CLIENT_ID=your_google_client_id GOOGLE_CLIENT_SECRET=your_google_client_secret # Microsoft OAuth MICROSOFT_CLIENT_ID=your_microsoft_client_id MICROSOFT_CLIENT_SECRET=your_microsoft_client_secret # Gitee OAuth GITEE_CLIENT_ID=your_gitee_client_id GITEE_CLIENT_SECRET=your_gitee_client_secret
可选的环境变量
# 安全配置 SECURE_COOKIES=true SAMESITE_STRICT=true CORS_ORIGIN=https://yourdomain.com # 日志配置 LOG_LEVEL=info ENABLE_AUTH_LOGS=true # 会话配置 MAX_SESSIONS_PER_USER=10 SESSION_CLEANUP_INTERVAL=3600
Deno Deploy 部署
- 连接 GitHub 仓库
在 Deno Deploy 控制台中连接你的 GitHub 仓库
- 配置环境变量
在项目设置中添加所有必需的环境变量
- 设置自定义域名
配置你的域名并确保 HTTPS 证书正常工作
- 更新 OAuth 回调 URL
在各个 OAuth 提供商中更新回调 URL 为生产域名
部署检查清单
- □ 所有环境变量已配置
- □ OAuth 应用回调 URL 已更新
- □ HTTPS 证书正常工作
- □ 认证流程测试通过
- □ 会话管理功能正常
🔧 故障排除
Q: OAuth 登录失败,显示 'invalid_client' 错误
A: 检查 OAuth 应用的 Client ID 和 Client Secret 是否正确配置,确保回调 URL 与 OAuth 应用设置中的 URL 完全匹配。
Q: 用户登录后立即被重定向到登录页面
A: 可能是 JWT 密钥配置错误或 Cookie 设置问题。检查 JWT_SECRET 环境变量,确保在生产环境中启用了 HTTPS。
Q: 会话管理 API 返回 401 错误
A: 确保请求包含有效的认证 Cookie 或 Authorization 头,检查 JWT 令牌是否过期。
Q: 在开发环境中 Cookie 无法设置
A: 在开发环境中禁用 Secure Cookie 标志,或使用 HTTPS 进行本地开发。
Q: 多个会话之间出现冲突
A: 检查会话存储实现,确保会话 ID 的唯一性,考虑实施会话清理机制。
调试技巧
启用详细日志
# 在 .env 中添加 LOG_LEVEL=debug ENABLE_AUTH_LOGS=true
检查 JWT 令牌
// 在浏览器控制台中 document.cookie .split(';') .find(c => c.includes('auth_token'))