NextJS与AWS Amplify的认证路由配置问题求助
NextJS + AWS Amplify 认证路由控制实现方案
核心实现思路
通过NextJS中间件拦截路由请求,结合AWS Amplify Auth API校验用户状态,根据状态重定向到对应页面。同时在页面组件内添加兜底校验,避免中间件失效的情况。
步骤1:确认Amplify配置正确
确保你的amplifyconfiguration.json已正确配置,且在NextJS项目中完成Amplify初始化:
// app/layout.tsx 或 pages/_app.tsx import { Amplify } from 'aws-amplify'; import amplifyconfig from '@/amplifyconfiguration.json'; Amplify.configure(amplifyconfig);
步骤2:编写中间件(middleware.ts)
在项目根目录创建middleware.ts,实现路由拦截与状态校验:
import { NextResponse } from 'next/server'; import type { NextRequest } from 'next/server'; import { Auth } from 'aws-amplify'; export async function middleware(request: NextRequest) { const path = request.nextUrl.pathname; // 定义需要登录才能访问的路由 const protectedRoutes = ['/dashboard', '/profile']; // 定义已登录用户禁止访问的路由 const authRoutes = ['/login', '/register']; let isAuthenticated = false; try { // 跳过缓存实时校验用户登录状态 await Auth.currentAuthenticatedUser({ bypassCache: true }); isAuthenticated = true; } catch (err) { // 用户未登录时会抛出错误,直接捕获标记为未认证 isAuthenticated = false; } // 已登录用户访问登录/注册页,重定向到仪表盘 if (authRoutes.includes(path) && isAuthenticated) { return NextResponse.redirect(new URL('/dashboard', request.url)); } // 未登录用户访问受保护路由,重定向到登录页 if (protectedRoutes.includes(path) && !isAuthenticated) { return NextResponse.redirect(new URL('/login', request.url)); } // 其他情况正常放行 return NextResponse.next(); } // 指定中间件生效的路由范围 export const config = { matcher: ['/dashboard/:path*', '/profile/:path*', '/login', '/register'], };
步骤3:页面组件内添加兜底校验
为避免中间件因缓存或配置问题失效,在对应页面添加组件级校验:
受保护页面示例(app/dashboard/page.tsx)
'use client'; import { useEffect, useState } from 'react'; import { Auth } from 'aws-amplify'; import { useRouter } from 'next/navigation'; export default function Dashboard() { const router = useRouter(); const [loading, setLoading] = useState(true); useEffect(() => { const checkAuth = async () => { try { await Auth.currentAuthenticatedUser(); } catch (err) { router.push('/login'); } finally { setLoading(false); } }; checkAuth(); }, [router]); if (loading) { return <div>加载中...</div>; } return <div>仪表盘内容</div>; }
登录页面示例(app/login/page.tsx)
'use client'; import { useEffect, useState } from 'react'; import { Auth } from 'aws-amplify'; import { useRouter } from 'next/navigation'; export default function Login() { const router = useRouter(); const [loading, setLoading] = useState(true); useEffect(() => { const checkAuth = async () => { try { await Auth.currentAuthenticatedUser(); router.push('/dashboard'); } catch (err) { // 用户未登录,正常显示登录页 } finally { setLoading(false); } }; checkAuth(); }, [router]); if (loading) { return <div>加载中...</div>; } return <div>登录表单</div>; }
常见问题排查
- 调用
Auth.currentAuthenticatedUser时必须添加bypassCache: true,避免缓存导致的状态判断延迟 - 中间件的
matcher配置要覆盖所有需要校验的路由,使用/:path*匹配子路由 - 若使用App Router,Amplify初始化建议放在Client Component或layout.tsx的客户端逻辑中,避免 hydration 错误
内容的提问来源于stack exchange,提问作者Murat
相关产品推荐
相关产品推荐

