如何在react中实现登录访问控制

4,489 阅读2分钟

首先对于前端页面来说:

  • 有的页面不需要登录就可以访问,比如,登录页
  • 有的页面需要登录后才能访问,比如,项目后台首页、内容管理等(除了登录页面,其他页面需要登录才能访问)

因此,就需要对项目进行登录访问控制,让需要登录才能访问的页面,必须在登录后才能访问。 在没有登录时,直接跳转到登录页面,让用户进行登录。

如何实现登录访问控制呢?

  • 分析:不管哪个页面都是通过路由来访问的,因此,需要从路由角度来进行控制
  • 思路:创建 AuthRoute 组件,判断是否登录,1 登录直接显示要访问的页面 2 没有登录跳转到登录页面

在 React 路由中并没有直接提供该组件,需要手动封装,来实现登录访问控制(类似于 Vue 路由的导航守卫)

react-router-dom官方文档中提供了事例

image.png

可以看出,在Route 组件上有个render属性,而render属性又可以接收一个函数,那么我们就可以在这个函数里面进行判断了

import {
  HashRouter as Router,
  Route,
  Switch,
  Redirect
} from 'react-router-dom'
import Layout from './pages/layout/index.jsx'
import Login from './pages/login/index.jsx'
import NotFount from './pages/NotFount/index.jsx'
import './app.css'
import { setToken } from './utils/Storage.js'
const App = function () {
  return (
    <div className='app' >
      <Router>
        <Switch>
          <Redirect path="/" to="/login" exact />
          <Route path="/login" component={Login} />
          {/* <Route path="/layout" component={Layout} /> */}
          <Route path="/layout" render={(props) => {
            if (props.location.pathname !== '/login') { //判断访问的是否是登录页面
              if (setToken()) {//判断有没有token值
                return <Route path="/layout" component={Layout} /> //如果有token就访问
              } else {
                return <Redirect path="/" to="/login" exact /> //如果没有token就回到登录页面
              }
            } else {
              return <Redirect path="/" to="/login" exact />
            }
          }}/>
          <Route component={NotFount} />
        </Switch>
      </Router>
    </div>
  )
}

export default App

有没有发现这样封装会有一个弊端,假如有N个组件,那我们就要写N个,这里我们可以封装一个组件

首先我们建立一个文件AuthRouter.jsx文件

把需要的文件都提取出来

 /* eslint-disable react/prop-types */
import React from 'react'
import {
  Route,
  Redirect
} from 'react-router-dom'
import { setToken } from '@/utils/Storage.js'
export default function AuthRouter (props) {
  const { path, component } = props
  return (
        <Route path="/layout" render={(props) => {
          if (props.location.pathname !== '/login') {
            if (setToken()) {
              return <Route path={path} component={component} />
            } else {
              return <Redirect path="/" to="/login" exact />
            }
          } else {
            return <Redirect path="/" to="/login" exact />
          }
        }}/>
  )
}

这样我们就封装好了,如果在有相应的登录访问控制组件,我们就可以直接调用,把相应的参数传递进去

/* eslint-disable react/prop-types */
import {
  HashRouter as Router,
  Route,
  Switch,
  Redirect
} from 'react-router-dom'
import Layout from './pages/layout/index.jsx'
import Login from './pages/login/index.jsx'
import NotFount from './pages/NotFount/index.jsx'
import './app.css'
import AuthRouter from '@/utils/AuthRouter'
const App = function () {
  return (
    <div className='app' >
      <Router>
        <Switch>
          <Redirect path="/" to="/login" exact />
          <Route path="/login" component={Login} />
          {/* <Route path="/layout" component={Layout} /> */}
        <AuthRouter path='/layout' component={Layout}></AuthRouter>
          <Route component={NotFount} />
        </Switch>
      </Router>
    </div>
  )
}

export default App