登陆访问控制
针对登陆才能访问的功能,使用axios拦截器技术手段来实现
针对登陆才能访问的页面,使用路由来控制,vue中就是导航守卫,react中也有路由控制的机制
登陆访问控制—>使用axios拦截器统一处理token
这个时候后台接口也要配合规划,在此处以/user开始的接口是需要添加请求头(token)的。
如果状态码是400的话就是token超时或者异常,直接移除token
import axios from "axios";
import { BASE_URL } from "./url";
import { getToken,removeToken } from "./auth";
const API = axios.create({
baseURL: BASE_URL,
});
// Add a request interceptor
API.interceptors.request.use(
function (config) {
// Do something before request is sent
// startWith主要是为了判断是不是以其为开头的,因为有此情况dai参数的/user?abc=1
console.log(config, config.url);
const { url } = config;
if (
url.startsWith("/user") &&
!url.startsWith("/user/login") &&
!url.startsWith("/user/registered")
) {
// 添加请求头
config.headers.Authorization = getToken();
}
return config;
},
function (error) {
// Do something with request error
return Promise.reject(error);
}
);
// Add a response interceptor
API.interceptors.response.use(
function (response) {
// Do something with response data
console.log("response",response);
const { data:{ status } } = response;
if(status === 400) {
// 此时说明token失效,失效的话就删除token
removeToken()
}
return response;
},
function (error) {
// Do something with response error
return Promise.reject(error);
}
);
export default API;
登陆访问控制—>控制访问页面(AuthRoute鉴权路由组件)
自己封装路由鉴权组件
老版本封装:
新版本封装,贼鸡儿复杂
AuthRoute鉴权路由组件 封装:
import React from 'react'
import { Route, Redirect } from 'react-router-dom'
import { isAuth } from '../../utils'
// <AuthRoute path="..." component={...}></AuthRoute>
// ({ component: Component, ...rest }) 从接收到的参数中直接解构
// ...rest是为了把path等属性传给Route
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
使用:
import { BrowserRouter as Router, Route,Redirect} from "react-router-dom";
import Home from "./pages/Home";
import CityList from "./pages/CityList";
import Map from "./pages/Map"
import HouseDetail from "./pages/HouseDetail";
import Login from "./pages/Login"
import AuthRoute from "./components/AuthRoute";
function App() {
return (
<Router>
<div className="App">
{/* 默认路由,实现路由的重定向 */}
<Route exact path="/" render={ ()=> <Redirect to="/home"/>}></Route>
<Route path="/home" component={Home}></Route>
<Route path="/citylist" component={CityList}></Route>
<AuthRoute path="/map" component={Map}></AuthRoute>
<Route path="/detail/:id" component={HouseDetail}></Route>
<Route path="/login" component={Login}></Route>
</div>
</Router>
);
}
export default App;
完善,修改登陆成功的跳转
登陆分为:1、直接点击登陆,直接去登陆。2、访问了需要登陆才能访问的页面,跳转到的登陆页面
直接去登陆可以看到是没有状态的:
const {
data: { body, description, status },
} = await API.post("/user/login", {
username: values.username,
password: values.password,
});
if (status === 200) {
localStorage.setItem("hkzf_token", body.token);
if (!props.location.state) {
// 直接进到了登陆页面
props.history.go(-1);
}else {
// 重定向过来的
//push:[home,login,map] 用push方法,在当前页返回的还是登陆页,而不是跳转页
//replace:[home,login(将map直接替换为了login,返回直接就到了home页面)]
props.history.replace(props.location.state.from.pathname)
}