对于一些 PC 端项目来说,
因此,就需要对项目进行登录访问控制,让需要登录才能访问的页面,必须在登录后才能访问。 在没有登录时,直接跳转到登录页面,让用户进行登录。
如何实现登录访问控制呢?
分析:不管哪个页面都是通过路由来访问的,因此,需要从路由角度来进行控制
思路:创建 AuthRoute
组件,判断是否登录,
1 登录直接显示要访问的页面
2 没有登录跳转到登录页面
复制代码
难点:react中没有导航守卫,需要自己封装
Route的作用是:当前path是/login能成功时,渲染组件。
复制代码
而我们的要求是:
当前path是/login 并且localStorage已经登录能成功时,渲染组件,否则渲染无权限组件。
render接收一个函数。它的入参很重要。
{
console.log(props);
return
}
}
复制代码
如果不补充 props给Layout组件,则渲染时,不会
{
// itcast_geek_pc
if(localStorage.getItem('itcast_geek_pc')) {
return
} else {
return ( )
}
}}>
复制代码
render 方法,指定该路由要渲染的组件内容(类似于 component 属性)。 // 使用方式:
复制代码
// 封装本地存储的操作
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
}
复制代码
{/* 路由规则 */}
// 导入封装的访问控制组件,替换原来的 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的path进行匹配,,,如果路径一致,那么这个对应的组件就会被渲染出来
Route没有判断用户是否登录的能力,只会根据path判断是否要渲染对应的组件。
需求:让Route组件能够有逻辑,能够判断用户是否登录,需要通过Route组件的render属性
(我的另一篇博客有详细介绍-非组件获取路由信息-)
优化页面跳转
utils/history.js
import { createHashHistory } from 'history'
const history = createHashHistory()
export default history
复制代码
import history from 'utils/history'
复制代码
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)
}
)