feat: implement password

This commit is contained in:
shinya
2025-06-23 22:58:16 +08:00
parent 44cd7d0ed3
commit a9ad984564
9 changed files with 199 additions and 23 deletions

View File

@@ -0,0 +1,53 @@
'use client';
import { usePathname, useRouter } from 'next/navigation';
import { useEffect } from 'react';
interface Props {
children: React.ReactNode;
}
export default function AuthProvider({ children }: Props) {
const router = useRouter();
const pathname = usePathname();
useEffect(() => {
// 登录页或 API 路径不做校验,避免死循环
if (pathname.startsWith('/login')) return;
const password =
typeof window !== 'undefined' ? localStorage.getItem('password') : null;
const fullPath =
typeof window !== 'undefined'
? window.location.pathname + window.location.search
: pathname;
// 没有密码直接跳转登录
if (!password) {
router.replace(`/login?redirect=${encodeURIComponent(fullPath)}`);
return;
}
// 有密码时验证
(async () => {
try {
const res = await fetch('/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ password }),
});
if (!res.ok) {
// 校验未通过,清理并跳转登录
localStorage.removeItem('password');
router.replace(`/login?redirect=${encodeURIComponent(fullPath)}`);
}
} catch (error) {
// 网络错误等也认为未登录
router.replace(`/login?redirect=${encodeURIComponent(fullPath)}`);
}
})();
}, [pathname, router]);
return <>{children}</>;
}