登录访问控制 | 您所在的位置:网站首页 › react路由匹配组件 › 登录访问控制 |
对于一些 PC 端项目来说, 有的页面不需要登录就可以访问,比如,登录页 有的页面需要登录后才能访问,比如,项目后台首页、内容管理等(除了登录页面,其他页面需要登录才能访问)因此,就需要对项目进行登录访问控制,让需要登录才能访问的页面,必须在登录后才能访问。 在没有登录时,直接跳转到登录页面,让用户进行登录。 如何实现登录访问控制呢? 分析:不管哪个页面都是通过路由来访问的,因此,需要从路由角度来进行控制 思路:创建 AuthRoute 组件,判断是否登录, 1 登录直接显示要访问的页面 2 没有登录跳转到登录页面 复制代码难点:react中没有导航守卫,需要自己封装 访问控制-用Route组件的render来解决Route的作用是:当前path是/login能成功时,渲染组件。 复制代码而我们的要求是: 当前path是/login 并且localStorage已经登录能成功时,渲染组件,否则渲染无权限组件。 render的基本用法render接收一个函数。它的入参很重要。 { console.log(props); return } } 复制代码如果不补充 props给Layout组件,则渲染时,不会 权限控制 { // itcast_geek_pc if(localStorage.getItem('itcast_geek_pc')) { return } else { return () } }}> 复制代码 访问控制-AuthRoute组件封装 分析 AuthRoute 鉴权路由组件 场景:限制某个页面只能在登录的情况下访问。 说明:在 React 路由中并没有直接提供该组件,需要手动封装,来实现登录访问控制(类似于 Vue 路由的导航守卫)。 如何封装?参考 react-router-dom 文档中提供的鉴权示例 。 如何使用?使用 AuthRoute 组件代替默认的 Route 组件,来配置路由规则。 AuthRoute 组件实际上就是对原来的 Route 组件做了一次包装,来实现了一些额外的功能。 render 方法,指定该路由要渲染的组件内容(类似于 component 属性)。 Redirect 组件:重定向组件,通过 to 属性,指定要跳转到的路由信息。 state 属性:表示给路由附加一些额外信息,此处,用于指定登录成功后要进入的页面地址。 // 使用方式: 复制代码 实现自己的AuthRoute组件 处理token的方法 // 封装本地存储的操作 const TOKEN_KEY = 'itcast_geek_pc' // 获取 token export function getToken () { return localStorage.getItem(TOKEN_KEY) } // 本地存储 token export function setToken (token) { localStorage.setItem(TOKEN_KEY, token) } // 删除 token export function removeToken () { localStorage.removeItem(TOKEN_KEY) } // 判断有无 token export function hasToken () { return !!getToken() } 复制代码 权限判断 import { hasToken } from '../utils/storage' import { Redirect, Route } from 'react-router-dom' import React from 'react' import PropTypes from 'prop-types' export default function AuthRoute (props) { console.log(props) const Com = props.component return ( { // 判断有无 token if (hasToken()) { // 有 token, 表示已经登录,可以访问需要登录才能访问的页面(如首页...) return } else { // 没有 token ,表示未登录,不能访问主页,跳转登录页 return } }} /> ) } AuthRoute.propTypes = { path: PropTypes.string.isRequired, component: PropTypes.func.isRequired } 复制代码 使用AuthRoute {/* 路由规则 */} // 导入封装的访问控制组件,替换原来的 Route 复制代码 登录成功处理 submit = async (values) => { const { mobile, code } = values console.log(this.props) try { const res = await login(mobile, code) // 存储token // localStorage.setItem('itcast_geek_pc', res.data.token) setToken(res.data.token) // 跳转到首页 const { state } = this.props.location if (state) { this.props.history.push(state.from.pathname) } else { this.props.history.push('/home') } message.success('登录成功', 1) } catch (err) { message.warning(err.response.data.message, 1) } } 复制代码 route组件的作用 复制代码Route组件会根据当前地址的中地址 和 Route的path进行匹配,,,如果路径一致,那么这个对应的组件就会被渲染出来 Route没有判断用户是否登录的能力,只会根据path判断是否要渲染对应的组件。 需求:让Route组件能够有逻辑,能够判断用户是否登录,需要通过Route组件的render属性 处理history(我的另一篇博客有详细介绍-非组件获取路由信息-) 优化页面跳转 封装history模块 history处理 utils/history.js import { createHashHistory } from 'history' const history = createHashHistory() export default history 复制代码 App.js修改 import history from 'utils/history' 复制代码 修改响应拦截器 用history.push来替代 import history from './history' // 响应拦截器 instance.interceptors.response.use( function (response) { return response.data }, function (error) { console.log(error.response) if (error.response.status === 401) { // token过期 removeToken() // 跳转到登录页 + history.push('/login') message.warning('用户信息已过期') } return Promise.reject(error) } ) 复制代码 |
CopyRight 2018-2019 实验室设备网 版权所有 |