React Router v6:阻止未登录用户访问时暴露受保护路由路径
解决受保护路由跳转时地址栏闪烁问题
要解决点击Profile链接时地址栏短暂显示受保护路径的问题,核心是把认证校验从路由渲染阶段提前到跳转触发前,不让受保护路径有机会出现在地址栏里。下面给你两种实用的实现方式:
方法一:自定义ProtectedLink组件(推荐)
封装一个带认证校验的导航组件,替换项目中原有的Link或NavLink,所有需要权限校验的跳转都用这个组件:
import { NavLink, useNavigate } from 'react-router-dom'; import { useAppSelector } from '../app/hooks'; // 替换成你项目中hooks的实际路径 import { selectUser } from '../features/user/userSlice'; // 替换成你项目中用户状态slice的实际路径 // 定义组件属性,兼容NavLink的所有原生属性 type ProtectedLinkProps = React.ComponentProps<typeof NavLink> & { redirectTo?: string; // 未登录时重定向的目标路径,默认是首页 }; export function ProtectedLink({ to, redirectTo = '/', ...props }: ProtectedLinkProps) { const { auth } = useAppSelector(selectUser); const navigate = useNavigate(); const handleClick = (e: React.MouseEvent) => { // 先阻止默认的跳转行为 e.preventDefault(); if (auth) { // 已登录,正常跳转到目标路径 navigate(to); } else { // 未登录,直接跳转到指定页面,用replace避免回退栈出现受保护路径 navigate(redirectTo, { replace: true }); } }; return <NavLink to={to} onClick={handleClick} {...props} />; }
使用方式
把原来的导航链接替换成这个组件即可:
// 原来的写法 <NavLink to="/profile">Profile</NavLink> // 替换后的写法 <ProtectedLink to="/profile">Profile</ProtectedLink>
方法二:手动拦截Link的点击事件
如果不想新增组件,可以直接在现有Link/NavLink上绑定点击事件,手动处理跳转逻辑:
import { NavLink, useNavigate } from 'react-router-dom'; import { useAppSelector } from '../app/hooks'; import { selectUser } from '../features/user/userSlice'; function Navbar() { const { auth } = useAppSelector(selectUser); const navigate = useNavigate(); const handleProfileNavigate = (e) => { // 阻止默认跳转 e.preventDefault(); if (!auth) { // 未登录直接跳首页 navigate('/', { replace: true }); return; } // 已登录正常跳转 navigate('/profile'); }; return ( <nav> <NavLink to="/">首页</NavLink> <NavLink to="/profile" onClick={handleProfileNavigate}>个人中心</NavLink> </nav> ); }
注意事项
原有的ProtectedRoute组件请保留,它负责拦截用户直接在地址栏输入受保护路径的场景,和前端跳转拦截形成双重权限保护,避免绕过导航组件直接访问的情况。
内容的提问来源于stack exchange,提问作者sakicmilan
相关产品推荐
相关产品推荐

