mirror of
https://github.com/woodchen-ink/Q58Connect.git
synced 2025-07-19 06:21:55 +08:00
feat: Restore OAuth parameter preservation during authentication flow
This commit is contained in:
parent
d83f60b0a9
commit
32aaf27b2e
@ -4,6 +4,7 @@ import { getClientByClientId } from "@/lib/dto/client";
|
|||||||
import { getCurrentUser } from "@/lib/session";
|
import { getCurrentUser } from "@/lib/session";
|
||||||
import { Authorizing } from "@/components/auth/authorizing";
|
import { Authorizing } from "@/components/auth/authorizing";
|
||||||
import { ErrorCard } from "@/components/auth/error-card";
|
import { ErrorCard } from "@/components/auth/error-card";
|
||||||
|
import { SaveOAuthParams } from "@/components/auth/save-oauth-params";
|
||||||
|
|
||||||
export interface AuthorizeParams {
|
export interface AuthorizeParams {
|
||||||
scope?: string;
|
scope?: string;
|
||||||
@ -21,7 +22,9 @@ export default async function OAuthAuthorization({
|
|||||||
// 检查用户是否已登录
|
// 检查用户是否已登录
|
||||||
const user = await getCurrentUser();
|
const user = await getCurrentUser();
|
||||||
if (!user?.id) {
|
if (!user?.id) {
|
||||||
redirect("/sign-in");
|
return (
|
||||||
|
<SaveOAuthParams searchParams={searchParams} redirectTo="/sign-in" />
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 验证必要的参数
|
// 验证必要的参数
|
||||||
|
38
src/app/authorize/page.tsx
Normal file
38
src/app/authorize/page.tsx
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
|
|
||||||
|
export default function AuthorizePage() {
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// 检查是否有待处理的 OAuth 请求
|
||||||
|
const pendingOAuth = localStorage.getItem("oauth_pending");
|
||||||
|
if (pendingOAuth) {
|
||||||
|
try {
|
||||||
|
const params = JSON.parse(pendingOAuth);
|
||||||
|
// 清除存储的 OAuth 参数
|
||||||
|
localStorage.removeItem("oauth_pending");
|
||||||
|
// 重定向到 OAuth 授权页面
|
||||||
|
const searchParams = new URLSearchParams(params);
|
||||||
|
router.push(`/oauth/authorize?${searchParams.toString()}`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to process OAuth params:", error);
|
||||||
|
router.push("/dashboard");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 如果没有待处理的 OAuth 请求,直接进入仪表板
|
||||||
|
router.push("/dashboard");
|
||||||
|
}
|
||||||
|
}, [router]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex min-h-screen items-center justify-center">
|
||||||
|
<div className="text-center">
|
||||||
|
<div className="mb-4 h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent"></div>
|
||||||
|
<p className="text-sm text-muted-foreground">正在处理...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
21
src/components/auth/save-oauth-params.tsx
Normal file
21
src/components/auth/save-oauth-params.tsx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import { redirect } from "next/navigation";
|
||||||
|
|
||||||
|
import { AuthorizeParams } from "@/app/(oauth)/oauth/authorize/page";
|
||||||
|
|
||||||
|
export function SaveOAuthParams({
|
||||||
|
searchParams,
|
||||||
|
redirectTo,
|
||||||
|
}: {
|
||||||
|
searchParams: AuthorizeParams;
|
||||||
|
redirectTo: string;
|
||||||
|
}) {
|
||||||
|
useEffect(() => {
|
||||||
|
localStorage.setItem("oauth_pending", JSON.stringify(searchParams));
|
||||||
|
window.location.href = redirectTo;
|
||||||
|
}, [searchParams, redirectTo]);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { useRouter, useSearchParams } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { Loader2, MessageCircleCode } from "lucide-react";
|
import { Loader2, MessageCircleCode } from "lucide-react";
|
||||||
|
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
@ -19,39 +19,15 @@ export function UserAuthForm({
|
|||||||
const [isLoading, setIsLoading] = React.useState<boolean>(false);
|
const [isLoading, setIsLoading] = React.useState<boolean>(false);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
const searchParams = useSearchParams();
|
|
||||||
|
|
||||||
const signIn = () => {
|
const signIn = () => {
|
||||||
React.startTransition(async () => {
|
React.startTransition(async () => {
|
||||||
try {
|
try {
|
||||||
const body: Record<string, any> = {};
|
|
||||||
|
|
||||||
// 如果存在 OAuth 参数,添加到请求体
|
|
||||||
if (searchParams?.has("client_id")) {
|
|
||||||
const oauthParams = new URLSearchParams();
|
|
||||||
[
|
|
||||||
"client_id",
|
|
||||||
"redirect_uri",
|
|
||||||
"response_type",
|
|
||||||
"state",
|
|
||||||
"scope",
|
|
||||||
].forEach((param) => {
|
|
||||||
const value = searchParams.get(param);
|
|
||||||
if (value) {
|
|
||||||
oauthParams.append(param, value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (oauthParams.toString()) {
|
|
||||||
body.oauth_params = oauthParams.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = await fetch("/api/auth/q58", {
|
const response = await fetch("/api/auth/q58", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
},
|
},
|
||||||
body: JSON.stringify(body),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok || response.status !== 200) {
|
if (!response.ok || response.status !== 200) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user