zoukankan      html  css  js  c++  java
  • react登录路由控制

    登录访问控制

    • AuthRoute 鉴权路由组件实现思路
    • 参照官网自己封装AuthRoute 鉴权路由组件
    • 实现修改登录成功后的跳转

    概述

    项目中的两种类型的功能和两种类型的页面:

    两种功能:

    • 登录后才能进行操作(比如:获取个人资料)
    • 不需要登录就可以操作(比如:获取房屋列表)

    两种页面:

    • 需要登录才能访问(比如:个人中心页)
    • 不需要登录即可访问(比如:首页)

    对于需要登录才能操作的功能使用 axios 拦截器 进行处理(比如:统一添加请求头 authorization等)

    对于需要登录才能访问的页面使用 路由控制

    功能处理-使用axios拦截器统一处理token

    • 在api.js 中,添加请求拦截器 (API.interceptors.request.user())
    • 获取到当前请求的接口路径(url)
    • 判断接口路径,是否是以/user 开头,并且不是登录或注册接口(只给需要的接口添加请求头)
    • 如果是,就添加请求头Authorization
    // 添加请求拦截器
    API.interceptors.request.use(config => {
      const { url } = config
      // 判断请求url路径
      if (
        url.startsWith('/user') &&
        !url.startsWith('/user/login') &&
        !url.startsWith('/user/registered')
      ) {
        // 添加请求头
        config.headers.Authorization = getToken()
      }
      return config
    })
    
    • 添加响应拦截器 (API.interceptors.response.use())
    • 判断返回值中的状态码
    • 如果是400,标示token超时或异常,直接移除token
    // 添加响应拦截器
    API.interceptors.response.use(response => {
      const { status } = response.data
      if (status === 400) {
        // 此时,说明 token 失效,直接移除 token 即可
        removeToken()
      }
      return response
    })
    

    页面处理-AuthRoute鉴权路由组件

    实现原理

    • 限制某个页面只能在登陆的情况下访问,但是在React路由中并没有直接提供该组件,需要手动封装,来实现登陆访问控制(类似与Vue路由的导航守卫)

    • 参数 react-router-dom的鉴权文档

    • AuthRoute 组件实际上就是对原来Route组件做了一次包装,来实现一些额外的功能

      • 使用

    • render方法:render props模式,指定该路由要渲染的组件内容

    • Redirect组件:重定向组件,通过to属性,指定要跳转的路由信息

    // 官网封装的核心逻辑代码
    // ...rest  把之前的组件中传递的属性原封不动传递过来
    function PrivateRoute({ component: Component, ...rest }) {
      return (
        <Route
          {...rest}
          // render方法: render props模式,指定该路由要渲染的组件内容
          render={props =>
            // 判断是否登陆,如果登陆,跳转配置的component,如果没有登陆,利用 Redirect组件来进行重定向
            fakeAuth.isAuthenticated ? (
              <Component {...props} />
            ) : (
              <Redirect
                to={{
                  pathname: "/login",
                  // 把当前的页面路径保存起来,方便用户登录后能够跳回当前页面
                  state: { from: props.location }
                }}
              />
            )
          }
        />
      );
    }
    

    封装AuthRoute鉴权路由组件

    • 在components目录中创建AuthRoute/index.js 文件
    • 创建组件AuthRoute并导出
    • 在AuthRoute组件中返回Route组件(在Route基础上做了一层包装,用于实现自定义功能)
    • 给Route组件,添加render方法,指定改组件要渲染的内容(类似与component属性)
    • 在render方法中,调用isAuth() 判断是否登陆
    • 如果登陆了,就渲染当前组件(通过参数component获取到要渲染的组件,需要重命名)
    • 如果没有登陆,就重定向到登陆页面,并且指定登陆成功后腰跳转的页面路径
    • 将AuthRoute组件接收到的props原样传递给Route组件(保证与Route组件使用方式相同)
    • 使用AuthRoute组件配置路由规则,验证是否实现页面的登陆访问控制
    const AuthRoute = ({ component: Component, ...rest }) => {
      return (
        <Route
          {...rest}
          render={props => {
            const isLogin = isAuth()
    
            if (isLogin) {
              // 已登录
              // 将 props 传递给组件,组件中才能获取到路由相关信息
              return <Component {...props} />
            } else {
              // 未登录
              return (
                <Redirect
                  to={{
                    pathname: '/login',
                    state: {
                      from: props.location
                    }
                  }}
                />
              )
            }
          }}
        />
      )
    }
    export default AuthRoute
    

    修改登录成功跳转

    • 登陆成功后,判断是否需要跳转到用户想要访问的页面(判断props.location.state 是否有值)
    • 如果不需要,则直接调用history.go(-1) 返回上一页
    • 如果需要,就跳转到from.pathname 指定的页面(推荐使用replace方法模式,不是push)
     // 表单的提交事件
      handleSubmit: async (values, { props }) => {
        ...
        if (status === 200) {
          // 登录成功
          localStorage.setItem('hkzf_token', body.token)
    
          /* 
            1 登录成功后,判断是否需要跳转到用户想要访问的页面(判断 props.location.state 是否有值)。
            2 如果不需要(没有值),则直接调用 history.go(-1) 返回上一页。
            3 如果需要,就跳转到 from.pathname 指定的页面(推荐使用 replace 方法模式,而不是 push)。
          */
          if (!props.location.state) {
            // 此时,表示是直接进入到了该页面,直接调用 go(-1) 即可
            props.history.go(-1)
          } else {
            // replace: [home, map]
            props.history.replace(props.location.state.from.pathname)
          }
        } else {
          // 登录失败
          Toast.info(description, 2, null, false)
        }
      }
    
  • 相关阅读:
    ubuntu高版本环境变量问题
    linux下可以和qq截屏比拟的工具hotshots
    如何以非 root 用户将应用绑定到 80 端口-ssh 篇
    mvn profile 深层次目录打参数核心配置
    java 判断字符串编码
    springmvc 传递和接收数组参数
    系统分层 manager层意义
    mysql insert中文乱码无法插入ERROR 1366 (HY000): Incorrect string value
    Apache Lens —— 统计数据分析查询接口
    云平台需要开发的底层功能
  • 原文地址:https://www.cnblogs.com/xm0328/p/14225514.html
Copyright © 2011-2022 走看看