fenghuo/apps/backend
longdayi bece0afb3d Merge branch 'main' of http://113.45.67.59:3003/insiinc/nice 2025-05-29 12:26:55 +08:00
..
src Merge branch 'main' of http://113.45.67.59:3003/insiinc/nice 2025-05-29 12:26:55 +08:00
.env.example add 2025-05-28 08:23:15 +08:00
README.md 05280823 2025-05-28 08:23:14 +08:00
package.json Merge branch 'main' of http://113.45.67.59:3003/insiinc/nice 2025-05-28 20:04:05 +08:00
tsconfig.json add 2025-05-28 20:00:36 +08:00

README.md

OIDC Provider Demo

这是一个基于 Hono 后端的 OpenID Connect (OIDC) Provider 演示应用使用了标准的OIDC架构设计。

功能特性

  • 完整的 OIDC Provider 实现
  • 支持授权码流程 (Authorization Code Flow)
  • 支持 PKCE (Proof Key for Code Exchange)
  • 内置认证处理器
  • JWT 令牌签发和验证
  • 用户信息端点
  • 令牌撤销
  • Redis 存储适配器
  • 内置登录页面

标准OIDC架构

使用内置认证处理器(推荐)

import { createOIDCProvider } from '@repo/oidc-provider';

// 使用内置认证处理器Provider自己处理登录
const oidcApp = createOIDCProvider({
  config: oidcConfig,
  useBuiltInAuth: true,
  builtInAuthConfig: {
    passwordValidator: validatePassword,
    sessionTTL: 24 * 60 * 60, // 24小时
    loginPageTitle: 'OIDC Demo 登录',
    brandName: 'OIDC Demo Provider',
  },
});

自定义认证处理器(高级用法)

import { createOIDCProvider, type AuthHandler } from '@repo/oidc-provider';

class MyAuthHandler implements AuthHandler {
  async getCurrentUser(c: Context): Promise<string | null> {
    // 检查用户认证状态
    // 例如从JWT token、session或cookie中获取用户ID
    const token = c.req.header('Authorization');
    return await verifyTokenAndGetUserId(token);
  }

  async handleAuthRequired(c: Context, authRequest: AuthorizationRequest): Promise<Response> {
    // 处理未认证用户
    // 例如:显示自定义登录页面或重定向到外部认证服务
    return this.showCustomLoginPage(c, authRequest);
  }
}

const oidcApp = createOIDCProvider({
  config: oidcConfig,
  authHandler: new MyAuthHandler()
});

启动服务

# 在项目根目录
cd apps/backend
bun run dev

服务将在 http://localhost:8000 启动。

当前配置

当前的 OIDC Provider 已配置为:

  • 使用内置认证处理器Provider自己处理所有登录逻辑
  • 支持标准OIDC授权码流程
  • 使用 Redis 存储令牌和会话

OIDC 端点

发现文档

GET http://localhost:8000/oidc/.well-known/openid-configuration

主要端点

  • 授权端点: http://localhost:8000/oidc/auth
  • 令牌端点: http://localhost:8000/oidc/token
  • 用户信息端点: http://localhost:8000/oidc/userinfo
  • JWKS端点: http://localhost:8000/oidc/.well-known/jwks.json
  • 撤销端点: http://localhost:8000/oidc/revoke

测试客户端

机密客户端 (Confidential Client)

Client ID: demo-client
Client Secret: demo-client-secret
重定向URI: 
  - http://localhost:3000/callback
  - http://localhost:8080/callback
  - https://oauth.pstmn.io/v1/callback

公共客户端 (Public Client)

Client ID: demo-public-client
重定向URI:
  - http://localhost:3000/callback
  - myapp://callback

测试用户

用户名: demouser
密码: password
用户ID (sub): demo-user

API 测试

运行测试脚本验证新API

cd apps/backend
bun run test-oidc.ts

授权流程

  1. 客户端发起授权请求: 访问 /oidc/auth 端点
  2. 检查用户认证: AuthHandler 检查用户是否已认证
  3. 用户认证: 如未认证,重定向到登录页面
  4. 生成授权码: 认证成功后生成授权码
  5. 交换访问令牌: 客户端使用授权码换取访问令牌
  6. 访问资源: 使用访问令牌访问用户信息等资源

配置说明

import { createOIDCProvider, DefaultAuthHandler } from '@repo/oidc-provider';

const oidcConfig = {
  issuer: 'http://localhost:8000/oidc',
  signingKey: 'your-secret-key',
  storage: redisAdapter,
  findClient: async (clientId) => { /* 查找客户端 */ },
  findUser: async (userId) => { /* 查找用户 */ },
  // ... 其他配置
};

// 方式1: 使用内置认证处理器(推荐)
const app1 = createOIDCProvider({
  config: oidcConfig,
  useBuiltInAuth: true,
  builtInAuthConfig: {
    passwordValidator: validatePassword,
    sessionTTL: 24 * 60 * 60,
    loginPageTitle: 'OIDC Demo 登录',
    brandName: 'OIDC Demo Provider',
  },
});

// 方式2: 使用自定义处理器(高级用法)
const app2 = createOIDCProvider({
  config: oidcConfig,
  authHandler: new CustomAuthHandler()
});

与 Next.js Web 应用集成

  1. 标准OIDC流程: Next.js 应用使用标准 oidc-client-ts 库
  2. 认证处理: OIDC Provider 自己处理所有用户认证和登录页面
  3. 令牌管理: OIDC Provider 负责生成和管理所有令牌
  4. 回调处理: Next.js 应用只需处理OIDC回调获取令牌

技术架构

  • 框架: Hono.js
  • 存储: Redis (令牌存储)
  • JWT: JOSE 库
  • PKCE: 支持 SHA256 和 plain 方法
  • 算法: HS256 (可配置 RS256, ES256)
  • 认证: 可自定义认证处理器

优势

相比之前的实现新API具有以下优势

  1. 简化配置: 只需要提供配置对象和认证处理器
  2. 灵活认证: 支持任意认证方式JWT、Session、OAuth等
  3. 清晰分离: 认证逻辑与OIDC协议逻辑分离
  4. 易于扩展: 通过实现 AuthHandler 接口轻松自定义
  5. 类型安全: 完整的 TypeScript 类型支持

开发说明

  • 修改客户端或用户数据:编辑 src/oidc-demo.ts
  • 自定义认证逻辑:实现 AuthHandler 接口
  • 配置调整:修改 oidcConfig 对象

快速测试

  1. Web界面测试 访问 http://localhost:8000 查看完整的测试界面

  2. 授权流程测试 访问 http://localhost:8000/oidc/auth?response_type=code&client_id=demo-client&redirect_uri=https://oauth.pstmn.io/v1/callback&scope=openid%20profile%20email&state=test-state

  3. Postman测试 使用以下配置在 Postman 中测试 OAuth 2.0:

    授权URL: http://localhost:8000/oidc/auth
    令牌URL: http://localhost:8000/oidc/token
    回调URL: https://oauth.pstmn.io/v1/callback
    Client ID: demo-client
    Client Secret: demo-client-secret
    作用域: openid profile email
    

完整的授权码流程

1. 授权请求

GET http://localhost:8000/oidc/auth?response_type=code&client_id=demo-client&redirect_uri=https://oauth.pstmn.io/v1/callback&scope=openid%20profile%20email&state=random-state

2. 用户登录

系统会自动重定向到登录页面,使用测试用户登录

3. 获取授权码

登录成功后会重定向到 redirect_uri 并携带授权码

4. 交换访问令牌

curl -X POST http://localhost:8000/oidc/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code&code=YOUR_CODE&redirect_uri=https://oauth.pstmn.io/v1/callback&client_id=demo-client&client_secret=demo-client-secret"

5. 访问用户信息

curl -X GET http://localhost:8000/oidc/userinfo \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

支持的作用域和声明

作用域 (Scopes)

  • openid - 必需的基础作用域
  • profile - 用户基本信息
  • email - 邮箱信息
  • phone - 电话号码
  • address - 地址信息

声明 (Claims)

  • sub - 用户唯一标识
  • name, given_name, family_name - 姓名信息
  • email, email_verified - 邮箱信息
  • phone_number, phone_number_verified - 电话信息
  • picture, profile, website - 个人资料
  • gender, birthdate, zoneinfo, locale - 基本信息
  • address - 地址信息
  • updated_at - 更新时间

安全注意事项

⚠️ 这是一个演示应用,不应用于生产环境!

生产环境部署时需要注意:

  1. 使用强密钥和安全的签名算法
  2. 实现真实的用户认证和会话管理
  3. 添加适当的安全头和 CSRF 保护
  4. 使用 HTTPS
  5. 实现客户端注册和管理
  6. 添加速率限制和监控
  7. 定期轮换密钥

开发和扩展

如需修改客户端或用户数据,编辑 src/oidc-demo.ts 文件中的 demoClientsdemoUsers 数组。

如需自定义认证逻辑,修改 src/index.ts 中的登录处理逻辑。