完成后你将能够
能建立不会先加载私有子路由的认证门禁,并解释为什么它仍不能替代服务端授权。
身份、权限与导航是三件事
认证回答“用户是谁”,授权回答“用户能否访问这个资源”,Router 门禁只负责导航体验。beforeLoad 可以阻止子路由继续加载并跳到登录页,但真正读取或修改私有数据的服务端入口必须再次认证并执行资源级授权。
在 pathless layout 集中门禁
父路由 beforeLoad 先于子路由执行;把私有页面放在 `_authenticated` 下面即可复用一处检查。使用回调参数中的 location.href 保存真实目标,不要读取可能落后的 resolvedLocation。登录页必须验证回跳目标属于本站,避免开放重定向。
import { Outlet, createFileRoute, redirect } from '@tanstack/react-router'
export const Route = createFileRoute('/_authenticated')({
beforeLoad: ({ context, location }) => {
if (!context.auth.user) {
throw redirect({
to: '/login',
search: { redirect: location.href },
})
}
return { user: context.auth.user }
},
component: () => <Outlet />,
})把异常与未登录分开
“没有会话”可以稳定跳转登录;认证服务超时、网络失败或配置错误是另一类故障,应进入可观测的错误恢复流程。若在 catch 中处理认证错误,必须重新抛出 Router redirect,不能把有意的控制流吞掉。
把本课变成可验证的能力
未登录用户在任何私有子路由 Loader 执行前被重定向,登录用户可以从 Context 得到类型化 user。
建立 `_authenticated` pathless layout,保护 dashboard 与 settings,并在登录后安全回到原本站内 URL。
测试未登录直达、已登录刷新、会话过期和恶意外部 redirect;服务端接口还必须独立拒绝无权限请求。
- 只隐藏导航链接,却允许私有 Loader 和服务端接口直接执行。
- 不验证 redirect 参数就跳转,造成开放重定向。