react实现路由守卫
高阶组件
思路:
封装一个高阶组件
通过sessionStorage里面是否有token获取去校验
第一步:封装一个路由组件,可以将路由的内容暂时写作一个对象数组,导出
第二步:封装一个高阶组件,里面有一个参数是路由组件作为参数
第三步:在props里面获取到路由组件,和props.location对象的URL中的hash
第四步:这时候的路由组件内容是一个数组,所以我们可以通过find()方法检验当前的hash是否合法(在我们的路由中)
第五步:路由合法且当前hash不需要权限(数组里有一个属性未布尔,来确定是否需要权限),不需要且未登录(!isLogin)就跳转到该页面
第六步:如果已经登录,就开始接下来的逻辑
- 如果以登陆,但是hash匹配到登录,则重定向到首页
- 如果路由合法,就跳转到对应路由
return(<Route path={pathname} component={targetRouterConfig.component}/>)
- 如果路由不合法,就跳转到404页面
第七步:如果未登录,开始以下逻辑
- 未登录,路由合法但是需要权限,跳转到登陆页面
- 未登录,路由不合法,跳转到404
路由封装:
/**
* 定义路由组件,将 auth 设置为 true,表示该路由需要权限校验
*/
import Admin from "./pages/Admin";
import Login from "./pages/Login";
import Error from "./pages/Error";
export const routerMap = [
{path: "/", name: "admin", component: Admin, auth: true},
{path: "/login", name: "Login", component: Login},
{path: "/error", name: "error", component: Error},
];
高阶函数封装
/**
* 路由守卫校验
*/
import React, {Component} from "react";
import {Route, Redirect} from "react-router-dom";
class FrontendAuth extends Component {
// eslint-disable-next-line no-useless-constructor
constructor(props) {
super(props);
}
render() {
const {routerConfig, location} = this.props;
const {pathname} = location;
const isLogin = localStorage.getItem("user");
console.log(pathname, isLogin);
console.log(location);
// 如果该路由不用进行权限校验,登录状态下登陆页除外
// 因为登陆后,无法跳转到登陆页
// 这部分代码,是为了在非登陆状态下,访问不需要权限校验的路由
const targetRouterConfig = routerConfig.find(
(item) => item.path === pathname
);
console.log(targetRouterConfig);
if (targetRouterConfig && !targetRouterConfig.auth && !isLogin) {
const {component} = targetRouterConfig;
return <Route exact path={pathname} component={component}/>;
}
if (isLogin) {
// 如果是登陆状态,想要跳转到登陆,重定向到主页
if (pathname === "/login") {
return <Redirect to="/"/>;
} else {
// 如果路由合法,就跳转到相应的路由
if (targetRouterConfig) {
return (
<Route path={pathname} component={targetRouterConfig.component}/>
);
} else {
// 如果路由不合法,重定向到 404 页面
return <Redirect to="/error"/>;
}
}
} else {
// 非登陆状态下,当路由合法时且需要权限校验时,跳转到登陆页面,要求登陆
if (targetRouterConfig && targetRouterConfig.auth) {
return <Redirect to="/login"/>;
} else {
// 非登陆状态下,路由不合法时,重定向至 404
return <Redirect to="/error"/>;
}
}
}
}
export default FrontendAuth;
高阶组件的使用
import './App.less';
import React, {Fragment} from "react";
import {Switch} from 'react-router-dom'
import FrontendAuth from "./FrontendAuth";
import {routerMap} from "./routerMap";
function App() {
return (
<Fragment>
{/*只匹配一个,匹配成功就不往下匹配,效率高*/}
<Switch>
<FrontendAuth routerConfig={routerMap}/>
</Switch>
</Fragment>
);
}
export default App;