From 08be0879f2285b15ad3f03c063b9d333d99dbb75 Mon Sep 17 00:00:00 2001 From: wood chen Date: Mon, 17 Feb 2025 05:14:04 +0800 Subject: [PATCH] feat: Enhance OAuth 2.0 documentation and user session metadata --- src/app/()/page.tsx | 63 +++++++++++++++++++++++++++++++++++++-------- src/auth.ts | 8 ++++++ 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/src/app/()/page.tsx b/src/app/()/page.tsx index 9d58b8d..5aabf76 100644 --- a/src/app/()/page.tsx +++ b/src/app/()/page.tsx @@ -95,7 +95,9 @@ export default function IndexPage() { {/* API Example */}
-

示例代码

+

+ OAuth 2.0 认证流程 +

重要提示:{" "} @@ -104,30 +106,69 @@ export default function IndexPage() {

-                  {`// 1. 重定向到授权页面(必须通过浏览器重定向,不能使用 AJAX/Fetch)
+                  {`// 1. 重定向到授权页面
 window.location.href = 'https://connect.q58.club/oauth/authorize?' + new URLSearchParams({
-  response_type: 'code',
-  client_id: 'your_client_id',
-  redirect_uri: 'https://your-app.com/callback'
+  response_type: 'code',      // 必填,固定值 'code'
+  client_id: 'your_client_id',// 必填,在控制台获取的客户端ID
+  redirect_uri: 'https://your-app.com/callback' // 必填,授权后的回调地址
 });
 
-// 2. 在回调页面获取访问令牌
+// 2. 获取访问令牌
 const response = await fetch('https://connect.q58.club/api/oauth/access_token', {
   method: 'POST',
+  headers: {
+    'Content-Type': 'application/x-www-form-urlencoded'
+  },
   body: new URLSearchParams({
-    code: '授权码',
-    redirect_uri: 'https://your-app.com/callback'
+    code: '授权码',  // 上一步回调地址获取的 code 参数
+    redirect_uri: 'https://your-app.com/callback'  // 必须与授权请求中的一致
   })
 });
-const { access_token } = await response.json();
+
+// 返回数据示例:
+{
+  "access_token": "at_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", // 访问令牌
+  "token_type": "bearer",   // 令牌类型
+  "expires_in": 604800      // 令牌有效期(秒)
+}
 
 // 3. 获取用户信息
 const userInfo = await fetch('https://connect.q58.club/api/oauth/user', {
   headers: {
-    'Authorization': \`Bearer \${access_token}\`
+    'Authorization': \`Bearer \${access_token}\`  // 使用上一步获取的访问令牌
   }
-}).then(res => res.json());`}
+}).then(res => res.json());
+
+// 返回数据示例:
+{
+  "id": "user_xxxxxx",           // 用户唯一标识
+  "email": "user@example.com",   // 用户邮箱
+  "username": "username",        // 用户名
+  "name": "用户昵称",            // 用户昵称
+  "avatarUrl": "https://...",   // 头像URL
+  "admin": false,               // 是否是管理员
+  "moderator": false,           // 是否是版主
+  "groups": ["group1", "group2"] // 用户所属的论坛用户组
+}`}
                 
+
+

+ 权限说明: +

+
    +
  • read_profile - 获取用户基本信息,包括邮箱、用户名等
  • +
  • groups - 获取用户所属的论坛用户组信息
  • +
  • admin - 获取用户的管理权限状态
  • +
+

+ 安全建议: +

+
    +
  • 请务必在服务器端验证 access_token 的有效性
  • +
  • 建议使用 HTTPS 确保数据传输安全
  • +
  • 请妥善保管 client_secret,不要泄露给客户端
  • +
+
diff --git a/src/auth.ts b/src/auth.ts index 17f715e..310d3b0 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -32,6 +32,12 @@ export const { handlers, auth, signIn, signOut } = NextAuth({ if (token.role) { session.user.role = token.role; } + if (token.moderator !== undefined) { + session.user.moderator = token.moderator; + } + if (token.groups) { + session.user.groups = token.groups; + } session.user.name = token.name; return session; @@ -47,6 +53,8 @@ export const { handlers, auth, signIn, signOut } = NextAuth({ token.picture = dbUser.avatarUrl; token.name = dbUser.name; token.role = dbUser.role; + token.moderator = dbUser.moderator; + token.groups = dbUser.groups; return token; },