一、用户登录
前端发送登录请求到后端,如果登录成功,后端会返回 token 给前端。前端需要将 token 保存到本地存储:
export default {data(){return {user:{username:'',password:''}}},methods: {async login() {const res = await this.$api.users.login(this.user);if(res.code) {localStorage.token = res.token; // token 保存到本地存储alert('登录成功');this.$router.replace('/home');} else {alert('账号或密码错误,登录失败。')}}}}
二、判断是否有 token
1、设置前置导航守卫
在路由配置文件中,找到需要登录才能访问的页面,添加对应的导航守卫:
const routes = [{path: '/home',component: HomeView,// 首页的前置导航守卫beforeEnter: (to, from, next) => {}}]
2、判断本地是否有 token
const routes = [{path: '/home',component: HomeView,// 首页的前置导航守卫beforeEnter: (to, from, next) => {const token = localStorage.token;if(token) {// 本地有 token} else {alert('你还未登录,请先登录');next('/login')}}}]
三、判断 token 是否过期
前端无法判断 token 是否过期,只能通过一个请求将 token 添加到请求头中,发送给后端,让后端来验证 token 是否有效。
if(token) {// 本地有 tokenconst res = await api.users.getInfo(); // 发送“获取用户信息”的请求console.log(res);} else {alert('你还未登录,请先登录');next('/login')}
1、统一处理请求头
找到 axios 的公共配置文件 utils/request.js,设置请求拦截器:
// 请求拦截器axios.interceptors.request.use(config => {const token = localStorage.token;if (token) {config.headers.Authorization = token;}return config;});
四、保存用户信息
1、设置用户初始值
我们需要先在主仓库中设置用户信息的初始值,以及修改用户信息的方法:
export default new Vuex.Store({state: {userInfo: null},mutations: {SET_USER_INFO(state, payload) {state.userInfo = payload;}}})
2、保存用户信息
在路由配置文件中,引入仓库对象,然后调用方法来保存用户信息到主仓库:
import store from '@/store'//...const routes = [{path: '/home',component: HomeView,beforeEnter: async (to, from, next) => {const token = localStorage.getItem('token');if (token) {// 发送请求验证token是否有效const res = await api.users.getInfo();if (res && res.code) {store.commit('SET_USER_INFO', res.data);}next();} else {alert('请先登录');next('/login');}},}]
五、渲染用户信息
在需要渲染用户信息的组件中,获取到仓库中的用户信息,渲染即可。
<p>欢迎你,{{ $store.state.userInfo.username }}</p>
六、处理 token 过期报错
找到 axios 的公共配置文件 utils/request.js,在相应拦截器中处理报错信息:
// 响应拦截器axios.interceptors.response.use(res => res.data, error => {if (error && error.response && error.response.status) {if (error.response.status == 401) {alert('登录状态已过期,请重新登录。');router.replace('/login');return;}}// 程序出现了报错,但不是 401 的错return Promise.reject(error);});
