React JS如何防范用户篡改Cookie非法访问受保护路由及端点
核心前提
前端层面无法完全阻止用户篡改本地存储的任意数据(包括Cookie、LocalStorage、IndexedDB等),所有前端路由防护本质是体验优化手段,绝对不能替代后端的接口权限校验。哪怕用户真的绕过前端路由进入了受保护页面,只要后端所有敏感接口都做了权限校验,用户也拿不到真实数据、无法执行非法操作,这才是安全的根本防线。
前端侧可落地的防范优化方案
以下方案可以大幅提升用户篡改Cookie绕过权限的成本,解决你当前遇到的问题:
不要明文存储权限字段到可读写Cookie
不要把整个用户对象序列化后明文存在Cookie中,仅在Cookie中存储服务端颁发的、不可篡改的身份凭证(比如带签名的JWT、SessionID),同时给Cookie加上安全属性:
HttpOnly:禁止前端JS读取Cookie,减少被恶意脚本篡改的可能Secure:仅在HTTPS环境下传输Cookie,避免中间人劫持篡改SameSite=Strict:防止CSRF攻击顺带篡改Cookie
用户的AccountType这类权限字段统一存在服务端,前端不要本地存储。
路由守卫的权限判断依赖可信数据源
不要从本地Cookie读取权限字段做判断,改为两种可信的获取方式:
- 应用初始化/路由切换时,调用后端的
/api/current-user接口拉取当前登录用户的真实权限信息,存在全局状态(React Context、Redux等)中,路由守卫从全局状态读取权限做判断 - 如果使用JWT做身份凭证,前端可以先校验JWT的签名合法性,篡改过Payload(比如修改AccountType)的JWT会直接验签失败,直接踢回登录页
优化后的路由守卫参考代码:
const RouteGuard = ({ component: Component, requiredAccountType, ...rest }) => { // 从全局Context拿后端返回的可信用户信息,而非从Cookie读取 const { user, loading } = useContext(UserContext); return ( <Route {...rest} render={(props) => { // 权限校验中显示加载态 if (loading) return <PageLoading />; // 未登录跳转登录页 if (!user) return <Redirect to="/login" />; // 权限不匹配跳转403 if (user.AccountType !== requiredAccountType) { return ( <Redirect to={{ pathname: "/403", state: { error: "You are not allowed to access this resource.", from: props.location.pathname, redirected: true, }, }} /> ); } return <Component {...props} />; }} /> ); }; // 使用时指定需要的权限等级 <Switch> <RouteGuard path="/records" exact requiredAccountType={2} component={Records} /> </Switch>- 应用初始化/路由切换时,调用后端的
受保护页面增加二次校验
就算用户绕过了路由守卫进入受保护页面,页面初始化时也要再次调用接口校验权限,校验不通过直接跳转403,所有涉及权限的操作(比如查询记录、修改数据)都要后端二次校验权限,拒绝非法请求。
内容的提问来源于stack exchange,提问作者demiglace
相关产品推荐
相关产品推荐

