mirror of
https://github.com/woodchen-ink/Q58Connect.git
synced 2025-07-18 14:01:55 +08:00
refactor: 优化 SSO 和 OAuth 重定向流程,改进参数处理和回调机制
This commit is contained in:
parent
f9c912e8c5
commit
1c0aa7e65f
17
README.md
17
README.md
@ -6,6 +6,23 @@
|
||||
|
||||
> shadcn安装组件的命令,举例: npx shadcn@latest add button
|
||||
|
||||
本项目是一个中间项目, 用于允许用户通过oauth2.0认证的方式接入本项目, 但是实际用户信息是本项目通过SSO连接到Discourse论坛获取的.
|
||||
|
||||
原始项目地址: https://github.com/Tuluobo/discourse-connect
|
||||
|
||||
本项目主要是进行了:
|
||||
|
||||
1. 前端页面内容补充
|
||||
2. 管理员的相关管理页面和统计页面
|
||||
3. 本系统用户可以查看自己应用的统计信息
|
||||
4. Navbar的导航菜单添加
|
||||
5. 本系统用户可以限制自己应用的允许授权使用者
|
||||
6. 首页说明的优化
|
||||
|
||||
整体流程应该是这样的:
|
||||
|
||||
用户登录接入应用 - 接入应用通过oauth2.0向本系统发起授权请求 - 本系统向Discourse论坛发起SSO请求 - 用户在Discourse论坛中进行登录 - Discourse论坛重定向到本系统, 并附带sso和sig参数 - 本系统通过sso和sig参数向Discourse论坛发起获取用户信息请求 - 本系统通过oauth2.0向接入应用发起回调请求, 并附带用户信息 - 接入应用通过oauth2.0向本系统发起获取用户信息请求 - 本系统通过oauth2.0向Discourse论坛发起获取用户信息请求 - 本系统返回用户信息给接入应用
|
||||
|
||||
## 项目概述
|
||||
|
||||
本项目提供了一个 OAuth 认证系统,允许其他应用程序使用 Discourse 论坛的用户账号进行身份验证。这样可以让用户使用他们已有的 Discourse 账号登录到您的应用程序,无需创建新的账号。
|
||||
|
@ -1,10 +1,11 @@
|
||||
"use server";
|
||||
|
||||
import { cookies } from "next/headers";
|
||||
import { redirect } from "next/navigation";
|
||||
import { signIn as nextSignIn } from "@/auth";
|
||||
|
||||
export async function signIn(data: Record<string, any>) {
|
||||
const { sso, sig, returnTo } = data;
|
||||
const { sso, sig } = data;
|
||||
|
||||
// 先进行 SSO 登录
|
||||
await nextSignIn("credentials", { sso, sig });
|
||||
@ -13,17 +14,17 @@ export async function signIn(data: Record<string, any>) {
|
||||
const params = new URLSearchParams(atob(sso));
|
||||
const returnSsoUrl = params.get("return_sso_url");
|
||||
|
||||
if (!returnSsoUrl) {
|
||||
// 如果没有 return_sso_url,检查是否有 OAuth 参数
|
||||
const searchParams = new URLSearchParams(returnTo);
|
||||
if (searchParams.has("client_id")) {
|
||||
// 如果是 OAuth 流程,重定向到授权页面
|
||||
redirect(`/oauth/authorize${returnTo}`);
|
||||
if (returnSsoUrl) {
|
||||
// 解析 return_sso_url 中的参数
|
||||
const returnUrl = new URL(returnSsoUrl);
|
||||
const hasOAuthParams = returnUrl.searchParams.has("client_id");
|
||||
|
||||
if (hasOAuthParams) {
|
||||
// 如果 URL 中包含 OAuth 参数,直接重定向(此时应该是 /authorize 页面)
|
||||
redirect(returnSsoUrl);
|
||||
}
|
||||
// 如果都没有,重定向到仪表板
|
||||
redirect("/dashboard");
|
||||
}
|
||||
|
||||
// 如果有 return_sso_url,重定向回 SSO 提供者
|
||||
redirect(returnSsoUrl);
|
||||
// 如果没有有效的重定向 URL,默认到仪表板
|
||||
redirect("/dashboard");
|
||||
}
|
||||
|
@ -15,12 +15,22 @@ export async function POST(req: Request) {
|
||||
const url = new URL(referer);
|
||||
const searchParams = url.searchParams.toString();
|
||||
|
||||
// 如果是从OAuth授权页面来的,保留OAuth参数
|
||||
const return_url = searchParams
|
||||
? `${hostUrl}/q58/callback?oauth=${btoa(searchParams)}`
|
||||
: `${hostUrl}/authorize`;
|
||||
// 保存原始的 OAuth 参数到 cookie,用于后续重定向
|
||||
if (searchParams) {
|
||||
cookies().set("oauth_params", searchParams, {
|
||||
maxAge: 60 * 10, // 10分钟过期
|
||||
path: "/",
|
||||
});
|
||||
}
|
||||
|
||||
const sso = btoa(`nonce=${nonce}&return_sso_url=${return_url}`);
|
||||
// 设置 SSO 回调地址,将 OAuth 参数编码后传递
|
||||
const return_url = searchParams
|
||||
? `${hostUrl}/authorize?${searchParams}` // 直接将 OAuth 参数附加到回调 URL
|
||||
: `${hostUrl}/dashboard`; // 如果没有 OAuth 参数,回到仪表板
|
||||
|
||||
const sso = btoa(
|
||||
`nonce=${nonce}&return_sso_url=${encodeURIComponent(return_url)}`,
|
||||
);
|
||||
const sig = hmacSHA256(sso, clientSecret).toString(Hex);
|
||||
|
||||
cookies().set(AUTH_NONCE, nonce, { maxAge: 60 * 10 });
|
||||
|
Loading…
x
Reference in New Issue
Block a user