mirror of
https://github.com/woodchen-ink/Q58Connect.git
synced 2025-07-18 05:51:55 +08:00
refactor: Migrate OAuth state management to API-based approach
This commit is contained in:
parent
67b434e692
commit
04d9ac38dc
@ -23,7 +23,9 @@ export default function AuthPage({ searchParams }: Props) {
|
||||
// 解码 OAuth 参数
|
||||
const params = JSON.parse(atob(oauthState));
|
||||
// 删除 cookie
|
||||
Cookies.remove("oauth_state", { path: "/" });
|
||||
fetch("/api/auth/oauth-state", { method: "DELETE" }).catch(
|
||||
console.error,
|
||||
);
|
||||
// 构建重定向 URL
|
||||
const searchParams = new URLSearchParams(params);
|
||||
router.push(`/oauth/authorize?${searchParams.toString()}`);
|
||||
|
@ -1,4 +1,6 @@
|
||||
import { Suspense } from "react";
|
||||
"use client";
|
||||
|
||||
import { useEffect } from "react";
|
||||
import { Metadata } from "next";
|
||||
import Link from "next/link";
|
||||
import { ChevronLeft, MessageCircleCode } from "lucide-react";
|
||||
@ -7,12 +9,29 @@ import { cn } from "@/lib/utils";
|
||||
import { buttonVariants } from "@/components/ui/button";
|
||||
import { UserAuthForm } from "@/components/auth/user-auth-form";
|
||||
|
||||
interface Props {
|
||||
searchParams: { state?: string };
|
||||
}
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Login",
|
||||
description: "Login to your account",
|
||||
};
|
||||
|
||||
export default function LoginPage() {
|
||||
export default function LoginPage({ searchParams }: Props) {
|
||||
useEffect(() => {
|
||||
// 如果有 state 参数,保存到 cookie
|
||||
if (searchParams.state) {
|
||||
fetch("/api/auth/oauth-state", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({ state: searchParams.state }),
|
||||
}).catch(console.error);
|
||||
}
|
||||
}, [searchParams.state]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Link
|
||||
@ -35,9 +54,7 @@ export default function LoginPage() {
|
||||
<span style={{ fontFamily: "Bahamas Bold" }}>Q58 Connect</span>
|
||||
</div>
|
||||
</div>
|
||||
<Suspense>
|
||||
<UserAuthForm />
|
||||
</Suspense>
|
||||
<UserAuthForm />
|
||||
<p className="px-8 text-center text-sm text-muted-foreground">
|
||||
By clicking continue, you agree to our{" "}
|
||||
<Link
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { cookies } from "next/headers";
|
||||
import { redirect } from "next/navigation";
|
||||
|
||||
import { getClientByClientId } from "@/lib/dto/client";
|
||||
@ -22,15 +21,10 @@ export default async function OAuthAuthorization({
|
||||
// 检查用户是否已登录
|
||||
const user = await getCurrentUser();
|
||||
if (!user?.id) {
|
||||
// 将 OAuth 参数保存到 cookie
|
||||
// 将 OAuth 参数编码为 base64
|
||||
const encodedParams = btoa(JSON.stringify(searchParams));
|
||||
cookies().set("oauth_state", encodedParams, {
|
||||
maxAge: 60 * 10, // 10分钟过期
|
||||
path: "/",
|
||||
httpOnly: true,
|
||||
secure: process.env.NODE_ENV === "production",
|
||||
});
|
||||
redirect("/sign-in");
|
||||
// 重定向到登录页面,将 OAuth 参数作为查询参数传递
|
||||
redirect(`/sign-in?state=${encodedParams}`);
|
||||
}
|
||||
|
||||
// 验证必要的参数
|
||||
|
25
src/app/api/auth/oauth-state/route.ts
Normal file
25
src/app/api/auth/oauth-state/route.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { cookies } from "next/headers";
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
export async function POST(req: Request) {
|
||||
try {
|
||||
const { state } = await req.json();
|
||||
cookies().set("oauth_state", state, {
|
||||
maxAge: 60 * 10, // 10分钟过期
|
||||
path: "/",
|
||||
httpOnly: true,
|
||||
secure: process.env.NODE_ENV === "production",
|
||||
});
|
||||
return NextResponse.json({ success: true });
|
||||
} catch (error) {
|
||||
return NextResponse.json(
|
||||
{ error: "Failed to save state" },
|
||||
{ status: 500 },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function DELETE() {
|
||||
cookies().delete("oauth_state");
|
||||
return NextResponse.json({ success: true });
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user