持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情
一.思路梳理
-
定义私有路由组件。在 components 目录中创建 PrivateRoute路由组件:实现路由的登录访问控制逻辑
-
有token,正常访问
-
没有token,重定向到登录页面,并传递要访问的路由地址
-
使用路由组件
-
将需要权限才能访问的页面,使用私有路由组件
二.token处理
src\utils\storage.ts
// 用来对{token: string, refresh_token: string }做本地持久化
import { Token } from '../types/data'
const TOKEN_KEY = 'geek-app'
// 获取 token
export function getToken (): Token {
if (localStorage.getItem(TOKEN_KEY)) {
return JSON.parse(localStorage.getItem(TOKEN_KEY) || '{}')
} else {
return {
token: '',
refresh_token: ''
}
}
}
// 设置 token
export function setToken (data: Token): void {
localStorage.setItem(TOKEN_KEY, JSON.stringify(data))
}
// 移除 token
export function removeToken (): void {
localStorage.removeItem(TOKEN_KEY)
}
// 判断是否登录(授权)
export function hasToken (): boolean {
return !!getToken().token
}
三.代码实现
1.封装组件
src\components\PrivateRoute.tsx
import { hasToken } from '../utils/storage'
import React from 'react'
import { Route, Redirect, RouteProps } from 'react-router-dom'
// children就是要展示的组件
export const PrivateRoute = ({ children, ...rest }: RouteProps) => {
return (
<Route
{...rest}
render={({ location }) =>
hasToken()
? (children)
: (
<Redirect
to={{
pathname: '/login',
state: { from: location }
}}
/>
)}
/>
)
}
注:
-
若render爆红可能是react-router-dom版本问题,可降版本也可将RouteProps换成any,也可以将render={(props):any
-
location可换成props,state: { from: location }换state: { from: location } -
使用...rest可以将相应代码规则添加进该路由规则中,如exact
2.使用组件
src\App.tsx
import { PrivateRoute } from './components/PrivateRoute'
function App () {
return (
<div className="app">
<Switch>
。。。
<PrivateRoute path="/profile/edit">
<ProfileEdit />
</PrivateRoute>
</div>)
}