Next.js集成Amazon Cognito:如何实现全局路由鉴权?
解决未登录可访问Dashboard页面的问题
你需要给/dashboard页面添加登录校验逻辑,确保只有已登录用户才能访问,以下是几种可行的实现方案:
方案一:直接用withAuthenticator包装Dashboard页面
和首页的处理方式一致,给Dashboard页面组件套用withAuthenticator高阶组件,未登录用户访问时会自动跳转登录界面:
- 打开
app/dashboard/page.tsx(无文件则创建对应页面),添加如下代码结构:
"use client"; import { Amplify } from 'aws-amplify'; import type { WithAuthenticatorProps } from '@aws-amplify/ui-react'; import { Button, withAuthenticator } from '@aws-amplify/ui-react'; import '@aws-amplify/ui-react/styles.css'; import config from '../amplifyconfiguration.json'; Amplify.configure(config); export function DashboardPage({ signOut, user }: WithAuthenticatorProps) { return ( <main className="flex min-h-screen flex-col p-6"> <h1>Dashboard 页面</h1> <p>当前登录用户:{user?.username}</p> <Button onClick={signOut}>退出登录</Button> </main> ); } export default withAuthenticator(DashboardPage);
方案二:封装通用权限校验组件
如果多个页面都需要登录校验,可以封装一个AuthGuard组件,避免重复代码:
- 在
app/ui目录下创建AuthGuard.tsx:
"use client"; import { useEffect, useState } from 'react'; import { Auth } from 'aws-amplify'; import { useRouter } from 'next/navigation'; export default function AuthGuard({ children }: { children: React.ReactNode }) { const [isAuthenticated, setIsAuthenticated] = useState(false); const [loading, setLoading] = useState(true); const router = useRouter(); useEffect(() => { const checkAuthStatus = async () => { try { // 检查当前是否有已登录用户 await Auth.currentAuthenticatedUser(); setIsAuthenticated(true); } catch (err) { // 未登录则跳转首页 router.push('/'); } finally { setLoading(false); } }; checkAuthStatus(); }, [router]); if (loading) { return <div>加载中...</div>; } return isAuthenticated ? <>{children}</> : null; }
- 在Dashboard页面中引入并使用该组件:
// app/dashboard/page.tsx import AuthGuard from '../ui/AuthGuard'; export default function DashboardPage() { return ( <AuthGuard> <main className="flex min-h-screen flex-col p-6"> <h1>Dashboard 页面</h1> {/* 页面内容 */} </main> </AuthGuard> ); }
方案三:在Dashboard路由的Layout中统一校验
如果/dashboard下有多个子页面,希望整个路由分支都需要登录,可以在Dashboard的布局文件中添加校验逻辑:
- 创建
app/dashboard/layout.tsx:
"use client"; import { useEffect, useState } from 'react'; import { Auth } from 'aws-amplify'; import { useRouter } from 'next/navigation'; export default function DashboardLayout({ children }: { children: React.ReactNode }) { const [loading, setLoading] = useState(true); const router = useRouter(); useEffect(() => { const checkAuth = async () => { try { await Auth.currentAuthenticatedUser(); } catch { // 未登录跳转首页 router.push('/'); } finally { setLoading(false); } }; checkAuth(); }, [router]); if (loading) { return <div>加载中...</div>; } return <>{children}</>; }
这样所有/dashboard/*的子路由都会自动校验登录状态,未登录用户无法访问。
注意事项
- 所有涉及Amplify Auth校验的组件/页面都需要标记
"use client",因为Auth API仅能在客户端环境运行。 - 若已在
ConfigureAmplify.tsx中全局配置过Amplify,页面内可以不用重复调用Amplify.configure(config),避免重复配置。
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

