在我的网站中,我在模式中使用登录表单而不是登录页面。我的问题是,如果用户尝试访问受保护的路由,甚至尝试执行一些需要首先进行身份验证的操作(添加书签或喜欢未登录的项目),如何打开此登录模式? 我想到的一件事是,在我的中间件内部,通过添加 login=true 参数将用户重定向到同一页面,然后从 queryparam 读取并显示模式。但我什至不知道这是不是一个好主意?还有其他解决方案吗? 我正在使用 Nextjs 13.4 和 React 18.2。
export async function middleware(request: NextRequest) {
const { url, nextUrl, cookies } = request;
const { value: token } = cookies.get('accessToken') ?? { value: null };
const hasVerifiedToken = token;
const isAuthPageRequested = protectedRoutes.includes(
request.nextUrl.pathname
);
if (isAuthPageRequested) {
if (!hasVerifiedToken) {
const response = NextResponse.next();
response.cookies.delete('token');
return response;
}
return;
}
if (!hasVerifiedToken) {
const searchParams = new URLSearchParams(nextUrl.searchParams);
searchParams.set('next', nextUrl.pathname);
searchParams.set('login', 'true'); // Add the login query parameter and then read it inside my pages to show modal
const response = NextResponse.redirect(
new URL(`/home?${searchParams}`, url)
);
response.cookies.delete('token');
return response;
}
return NextResponse.next();
}
export const config = { matcher: ['/profile/:path*', '/protected/:path*'] };
您可以考虑使用 React Context 和钩子来处理身份验证状态和模式可见性。这样,您可以全局管理状态并避免在页面之间传递查询参数。
AuthContext代码概念,
import { createContext, useContext, useState } from 'react'
const AuthContext = createContext(undefined)
export const AuthProvider= ({ children }) => {
const [isAuthenticated, setIsAuthenticated] = useState(false)
return (
<AuthContext.Provider value={{ isAuthenticated, setIsAuthenticated }}>
{children}
</AuthContext.Provider>
)
}
export const useAuth = () => useContext(AuthContext)
然后用 AuthProvider 包装您的应用程序...
登录成功后即可将 isAuthenticated 设置为 true 。
然后在受保护的路由或组件中使用 useAuth 挂钩,
// ...your protected route or component...
import { useAuth } from 'path-to-your-authContext'
function ProtectedRoute() {
const { isAuthenticated } = useAuth()
// Redirect or show modal based on isAuthenticated state.
return <div>Your protected content here</div>
}