Refactor authentication redirection logic
- Introduce a new `auth-redirect` module to manage safe return paths for login and redirection. - Update the login page to utilize `readReturnToFromLocation` for redirecting users post-login. - Modify the `AuthGate` component to use `loginPathWithReturnTo` for redirecting unauthorized users, enhancing security and user experience. - Adjust API request handling to incorporate the new redirection logic, ensuring users are directed to the appropriate login page with return paths.
This commit is contained in:
@@ -4,6 +4,7 @@ import { FormEvent, useEffect, useState } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { LockKeyhole, LogIn, Video } from "lucide-react";
|
||||
import { useAuth } from "@/components/auth/AuthProvider";
|
||||
import { readReturnToFromLocation } from "@/lib/auth-redirect";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
@@ -24,7 +25,7 @@ export default function LoginPage() {
|
||||
|
||||
useEffect(() => {
|
||||
if (!loading && user) {
|
||||
router.replace("/");
|
||||
router.replace(readReturnToFromLocation());
|
||||
}
|
||||
}, [loading, router, user]);
|
||||
|
||||
@@ -34,7 +35,7 @@ export default function LoginPage() {
|
||||
setSubmitting(true);
|
||||
try {
|
||||
await login(username.trim(), password);
|
||||
router.replace("/");
|
||||
router.replace(readReturnToFromLocation());
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : "登录失败");
|
||||
} finally {
|
||||
|
||||
@@ -4,6 +4,7 @@ import type { ReactNode } from "react";
|
||||
import { useEffect } from "react";
|
||||
import { usePathname, useRouter } from "next/navigation";
|
||||
import { AppShell } from "@/components/layout/AppShell";
|
||||
import { loginPathWithReturnTo } from "@/lib/auth-redirect";
|
||||
import { useAuth } from "./AuthProvider";
|
||||
|
||||
export function AuthGate({ children }: { children: ReactNode }) {
|
||||
@@ -15,9 +16,9 @@ export function AuthGate({ children }: { children: ReactNode }) {
|
||||
|
||||
useEffect(() => {
|
||||
if (!loading && !user && !isLoginPage) {
|
||||
router.replace("/login");
|
||||
router.replace(loginPathWithReturnTo(pathname));
|
||||
}
|
||||
}, [isLoginPage, loading, router, user]);
|
||||
}, [isLoginPage, loading, pathname, router, user]);
|
||||
|
||||
if (isLoginPage) {
|
||||
return <>{children}</>;
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
* 注意:api_key 读取时后端永远打码,写回打码占位符表示"不改 key"(写时哨兵)。
|
||||
*/
|
||||
|
||||
import { loginPathWithReturnTo } from "@/lib/auth-redirect";
|
||||
|
||||
export const API_BASE =
|
||||
process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8000";
|
||||
|
||||
@@ -20,7 +22,9 @@ async function request<T>(path: string, init?: RequestInit): Promise<T> {
|
||||
typeof window !== "undefined" &&
|
||||
!path.startsWith("/api/auth/")
|
||||
) {
|
||||
window.location.href = "/login";
|
||||
window.location.href = loginPathWithReturnTo(
|
||||
window.location.pathname + window.location.search,
|
||||
);
|
||||
}
|
||||
if (!res.ok) {
|
||||
let detail = `请求失败 (${res.status})`;
|
||||
|
||||
21
frontend/src/lib/auth-redirect.ts
Normal file
21
frontend/src/lib/auth-redirect.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
/** Internal path safe to use as a post-login redirect target. */
|
||||
export function getSafeReturnTo(
|
||||
value: string | null | undefined,
|
||||
): string | null {
|
||||
if (!value) return null;
|
||||
if (!value.startsWith("/") || value.startsWith("//")) return null;
|
||||
if (value === "/login" || value.startsWith("/login?")) return null;
|
||||
return value;
|
||||
}
|
||||
|
||||
export function loginPathWithReturnTo(returnTo: string): string {
|
||||
const safe = getSafeReturnTo(returnTo);
|
||||
if (!safe) return "/login";
|
||||
return `/login?returnTo=${encodeURIComponent(safe)}`;
|
||||
}
|
||||
|
||||
export function readReturnToFromLocation(): string {
|
||||
if (typeof window === "undefined") return "/";
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
return getSafeReturnTo(params.get("returnTo")) ?? "/";
|
||||
}
|
||||
Reference in New Issue
Block a user