Athena 正在加载...

认证系统接入指南

完整的 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 应用

  1. 访问 GitHub Developer Settings
  2. 点击 "New OAuth App"
  3. 填写应用信息:
    • Application name: 你的应用名称
    • Homepage URL: https://yourdomain.com
    • Authorization callback URL: https://yourdomain.com/api/auth/callback?provider=github
  4. 获取 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 应用

  1. 访问 Google Cloud Console
  2. 创建新项目或选择现有项目
  3. 启用 Google+ API
  4. 创建 OAuth 2.0 客户端 ID
  5. 配置授权重定向 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

查询参数

参数类型说明
redirectstring登录成功后的重定向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 部署

  1. 连接 GitHub 仓库

    在 Deno Deploy 控制台中连接你的 GitHub 仓库

  2. 配置环境变量

    在项目设置中添加所有必需的环境变量

  3. 设置自定义域名

    配置你的域名并确保 HTTPS 证书正常工作

  4. 更新 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'))