diff --git a/README.md b/README.md index b39b445..5431af9 100644 --- a/README.md +++ b/README.md @@ -63,55 +63,7 @@ Q58论坛网址: https://q58.club ## 用户应用接入本系统oauth2.0认证的方式: -1. 发起授权请求 - 将用户重定向到授权页面 - -const authUrl = 'https://connect.q58.club/oauth/authorize?' + -new URLSearchParams({ -response_type: 'code', // 必填,固定值 -client_id: 'your_client_id', // 必填,您的应用ID -redirect_uri: 'https://your-app.com/callback', -state: 'random_state', // 建议提供,防CSRF攻击 -scope: 'read_profile' // 可选,默认read_profile -}); - -window.location.href = authUrl; - -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: '授权码', // 回调参数中的code -redirect_uri: 'https://your-app.com/callback' -}) -}); - -const { access_token, expires_in } = await response.json(); - -3. 获取用户信息 - 使用访问令牌获取用户数据 - -const userInfo = await fetch('https://connect.q58.club/api/oauth/user', { -headers: { -'Authorization': `Bearer ${access_token}` -} -}).then(res => res.json()); - -// 返回数据示例: -{ -"id": "user_xxx", -"email": "user@example.com", -"username": "username", -"name": "用户昵称", -"avatar_url": "https://...", -"groups": ["group1", "group2"] -} +写在"src\app\()\page.tsx"里了. ## 添加新功能的准则 diff --git a/oauth2.0的授权模式.txt b/oauth2.0的授权模式.txt new file mode 100644 index 0000000..21d8f86 --- /dev/null +++ b/oauth2.0的授权模式.txt @@ -0,0 +1,75 @@ +授权码模式(Authorization Code) +第一步:获取授权码 + +授权码请求链接格式: + +http://localhost:8080/oauth/authorize?client_id=123456&response_type=code&scope=all&redirect_url=http://localhost:8080/oauth/token +返回的JSON格式: + +{ + "code": "123456", + "state": "123456" +} +第二步:申请令牌 + +令牌请求链接格式: + +http://localhost:8080/oauth/token?client_id=123456&client_secret=123456&grant_type=authorization_code&code=123456&redirect_url=http://localhost:8080/oauth/callback +返回的JSON格式: + +{ + "access_token": "123456", + "token_type": "bearer", + "scope": "read", + "refresh_token": "123456" +} +资源请求链接格式: + +http://localhost:8080/oauth/resource?access_token=123456 +返回的JSON格式: + +{ + "resource": "123456" +} +简化模式(Implicit) +简化模式跳过授权码,直接获取访问令牌,适用于没有后台服务程序的单页面应用。 + +令牌请求链接格式: + +http://localhost:8080/oauth/token?client_id=123456&client_secret=123456&response_type=token&scope=all&redirect_url=http://localhost:8080/oauth/callback +返回的JSON格式: + +{ + "access_token": "123456", + "token_type": "bearer", + "scope": "read", + "refresh_token": "123456" +} +密码模式(Password) +用户通过客户端使用用户名和密码向授权服务器请求授权,授权服务器向客户端发送访问令牌和更新令牌。 + +请求链接格式: + +http://localhost:8080/oauth/token?client_id=123456&client_secret=123456&grant_type=password&username=admin&password=admin +返回的JSON格式: + +{ + "access_token": "123456", + "token_type": "bearer", + "scope": "read", + "refresh_token": "123456" +} +客户端模式(Client Credentials) +客户端以自己的名义使用客户端ID和密钥向授权服务器请求授权,最简单的授权模式。 + +请求链接格式: + +http://localhost:8080/oauth/token?client_id=123456&client_secret=123456&grant_type=client_credentials +返回的JSON格式: + +{ + "access_token": "123456", + "token_type": "bearer", + "scope": "read", + "refresh_token": "123456" +} \ No newline at end of file diff --git a/src/app/()/page.tsx b/src/app/()/page.tsx index 9f25910..8257c2f 100644 --- a/src/app/()/page.tsx +++ b/src/app/()/page.tsx @@ -1,6 +1,15 @@ import Link from "next/link"; -import { ArrowRight, CheckCircle2, Code2, Lock, Users } from "lucide-react"; +import { + ArrowDownToLine, + ArrowRight, + CheckCircle2, + Code2, + Lock, + Send, + Users, +} from "lucide-react"; +import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import { Button } from "@/components/ui/button"; import { Card, @@ -9,15 +18,10 @@ import { CardHeader, CardTitle, } from "@/components/ui/card"; +import { CodeBlock } from "@/components/ui/code-block"; import { Container } from "@/components/ui/container"; import { Section } from "@/components/ui/section"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; -import { - TypographyH1, - TypographyH2, - TypographyLead, - TypographyMuted, -} from "@/components/ui/typography"; import { Header } from "@/components/layout/header"; export default function HomePage() { @@ -75,11 +79,11 @@ export default function HomePage() {
-
- {`const authUrl = 'https://connect.q58.club/oauth/authorize?' +
+
+ {/* */}
+
+
+
+
+
+ 1
+
+
+ 发起OAuth授权请求
+
+ 构建授权URL并重定向用户到授权页面
+
+
+
+
+
+
+
+ 请求地址
+
+ GET https://connect.q58.club/oauth/authorize
+
+
+
+
+ 请求参数
+
+ {`const authUrl = 'https://connect.q58.club/oauth/authorize?' +
new URLSearchParams({
- response_type: 'code', // 必填,固定值
+ response_type: 'code', // 必填,固定值为"code"
client_id: 'your_client_id', // 必填,您的应用ID
- redirect_uri: 'https://your-app.com/callback',
- state: 'random_state', // 建议提供,防CSRF攻击
- scope: 'read_profile' // 可选,默认read_profile
+ redirect_uri: 'https://your-app.com/callback', // 必填,回调地址
+ scope: 'read_profile' // 可选,权限范围,默认read_profile
});
window.location.href = authUrl;`}
-
-
-
-
-
-
-
-
- 2. 处理授权回调
-
- 在回调地址处理授权结果
-
-
-
-
-
- {`// 获取访问令牌
-const response = await fetch('https://connect.q58.club/api/oauth/access_token', {
+
+
+
+
+
+ 授权响应
+
+
+ 用户授权后,将重定向到您的回调地址:
+
+
+
+ https://your-app.com/callback?code=ac_xxxxxx...
+
+
+
+ 授权码说明:
+
+ - 格式:ac_前缀 + 40位随机字符
+ - 有效期:10分钟
+ - 使用限制:仅可使用一次
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2
+
+
+ 使用授权码交换访问令牌
+
+ 在服务器端使用授权码换取访问令牌
+
+
+
+
+
+
+
+ 请求地址
+
+ POST
+ https://connect.q58.club/api/oauth/access_token
+
+
+
+
+ 请求示例
+
+ {`const response = await fetch('https://connect.q58.club/api/oauth/access_token', {
method: 'POST',
headers: {
- 'Content-Type': 'application/x-www-form-urlencoded'
+ 'Content-Type': 'application/x-www-form-urlencoded',
+ 'Authorization': 'Basic ' + btoa(client_id + ':' + client_secret)
},
body: new URLSearchParams({
- code: '授权码', // 回调参数中的code
- redirect_uri: 'https://your-app.com/callback'
+ code: 'ac_xxxxx', // 必填,授权码
+ redirect_uri: 'https://your-app.com/callback' // 必填,与请求授权码时相同
})
-});
+});`}
+
+
-const { access_token, expires_in } = await response.json();`}
-
-
-
-
-
-
-
-
- 3. 获取用户信息
-
- 使用访问令牌获取用户数据
-
-
-
-
-
- {`const userInfo = await fetch('https://connect.q58.club/api/oauth/user', {
- headers: {
- 'Authorization': \`Bearer \${access_token}\`
- }
-}).then(res => res.json());
-
-// 返回数据示例:
-{
- "id": "user_xxx",
- "email": "user@example.com",
- "username": "username",
- "name": "用户昵称",
- "avatar_url": "https://...",
- "groups": ["group1", "group2"]
+
+
+ 响应数据
+
+
+
+ {`{
+ "access_token": "at_xxxxxxxx", // 访问令牌
+ "token_type": "bearer", // 令牌类型,固定为bearer
+ "expires_in": 604800 // 令牌有效期,单位秒(7天)
}`}
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 3
+
+
+ 获取用户信息
+
+ 使用访问令牌获取已授权用户的详细信息
+
+
+
+
+
+
+
+ 请求地址
+
+ GET https://connect.q58.club/api/oauth/user
+
+
+
+
+ 请求示例
+
+ {`const userInfo = await fetch('https://connect.q58.club/api/oauth/user', {
+ headers: {
+ 'Authorization': \`Bearer \${access_token}\` // 使用获取到的访问令牌
+ }
+}).then(res => res.json());`}
+
+
+
+
+
+ 响应数据
+
+
+
+ {`{
+ "id": "user_xxx", // 用户唯一标识
+ "email": "user@example.com",// 邮箱地址
+ "username": "username", // 用户名
+ "name": "用户昵称", // 显示名称
+ "avatar_url": "https://...",// 头像URL
+ "admin": false, // 是否管理员
+ "groups": ["group1"], // 用户组
+}`}
+
+
+
+
+
+
+
+
+ {children}
+
+