如何让React路由仅在存在指定查询字符串参数时才可访问?
问题结论
你无法通过将路由写为<Route path={${match.path}/product/:id?auth} />的方式实现需求。
核心原因
React Router的path配置仅匹配URL的路径部分,不会处理?之后的查询参数段,你把查询参数规则写到path里完全不会生效,只要路径符合${match.path}/product/:id的规则,不管有没有携带auth参数,都会匹配到该路由。
正确实现方案
你可以通过两种常用方式实现鉴权逻辑:
方式1:用高阶组件做路由守卫
先封装通用鉴权高阶组件,包裹需要校验的页面组件:
// 鉴权高阶组件示例(React Router v5版本) import { Redirect } from 'react-router-dom'; const withAuthCheck = (TargetComponent) => { return (props) => { const query = new URLSearchParams(props.location.search); const authCode = query.get('auth'); // 自定义校验规则,此处示例判断auth是否等于指定值 if (authCode !== '123456') { // 校验不通过跳转至无权限页或首页 return <Redirect to="/403" /> } // 校验通过渲染目标页面 return <TargetComponent {...props} /> } }
路由保持原有路径配置,替换component为包裹后的组件即可:
<Route path={`${match.path}/product/:id`} component={withAuthCheck(ProductPage)} />
方式2:页面组件内部做校验
直接在ProductPage组件的副作用中做参数校验:
// React Router v5 示例 import { useHistory, useLocation } from 'react-router-dom'; import { useEffect } from 'react'; const ProductPage = () => { const history = useHistory(); const location = useLocation(); useEffect(() => { const query = new URLSearchParams(location.search); const authCode = query.get('auth'); if (authCode !== '123456') { history.push('/403'); } }, [location, history]); // 剩余页面逻辑 // ... }
如果你使用的是React Router v6版本,只需要把跳转相关的API替换为v6对应的
Navigate组件、useNavigate钩子即可,鉴权的核心逻辑完全一致。
内容的提问来源于stack exchange,提问作者qweeee
相关产品推荐
相关产品推荐

