路由鉴权组件

272 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第15天,点击查看活动详情

大家好,我是大帅子,今天给大家讲一下路由鉴权组件,下面我们直接开始吧

封装鉴权路由组件

目标

能够封装鉴权路由组件实现登录访问控制功能

思路

react中没有路由守卫,但是类似的功能有现成的。参考:

v5.reactrouter.com/web/example…

步骤

  1. 定义私有路由组件。在 components 目录中创建 PrivateRoute路由组件:实现路由的登录访问控制逻辑

    • 有token,正常访问
    • 没有token,重定向到登录页面,并传递要访问的路由地址
  2. 使用路由组件

    1. 将需要权限才能访问的页面,使用私有路由组件

核心代码

定义组件

components/PrivateRoute.tsx 中:

import { hasToken } from '@/utils/storage'
import { Route, Redirect, RouteProps } from 'react-router-dom'export const PrivateRoute = ({ children, ...rest }: RouteProps) => {
  return (
    <Route
      {...rest}
      render={props => {
        if (hasToken()) {
          return children
        }
​
        return (
          <Redirect
            to={{
              pathname: '/login',
              state: {
                from: props.location.pathname // 回跳地址
              }
            }}
          />
        )
      }}
    />
  )
}

App.tsx 中:

import { PrivateRoute } from '@/components/PrivateRoute'const App = () => {
  return (
    // ...
    <PrivateRoute path="/profile/edit">
      <ProfileEdit />
    </PrivateRoute>
  )
}

pages/Layout/Layout.tsx 中:

import { PrivateRoute } from '@/components/AuthRoute'const Layout = () => {
  // ...
  return (
    // ...
    <PrivateRoute path="/home/profile">
      <Profile></Profile>
    </PrivateRoute>
  )
}

登录时跳转到相应页面

目标

能够在登录时根据重定向路径跳转到相应页面:如果是因为被privateRoute给拦截到login的,当login登录成功之后,要回到原页面

思路

步骤

  1. 在 Login 组件中导入 useLocation 来获取路由重定向时传入的 state

  2. 调用 useLocation hook 时,指定 state 的类型

  3. 登录完成跳转页面时,判断 state 是否存在

    1. 如果存在,跳转到 state 指定的页面
    2. 如果不存在,默认跳转到首页

核心代码

pages/Login/Login.tsx 中

import { useLocation } from 'react-router-dom'const Login = () => {
  // 注意: state 可能是不存在的,所以,类型中要明确包含不存在的情况,即 undefined
  const location = useLocation<{ from: string } | undefined>()
​
  const onFinish = async (values: LoginForm) => {
    // ...
    Toast.show({
      afterClose: () => {
        if (location.state) {
          return history.replace(location.state.from)
        }
​
        history.replace('/home/index')
      }
    })
  }
}

好了,这边已经给大家介绍到这里,以上是我自己的理解,希望可以帮到大家, 欢迎留言我这边一定会第一时间给大家解答,喜欢的可以点赞收藏,
🐣---->🦅        还需努力!大家一起进步!!!