一、用户登录

前端发送登录请求到后端,如果登录成功,后端会返回 token 给前端。前端需要将 token 保存到本地存储:

  1. export default {
  2. data(){
  3. return {
  4. user:{
  5. username:'',
  6. password:''
  7. }
  8. }
  9. },
  10. methods: {
  11. async login() {
  12. const res = await this.$api.users.login(this.user);
  13. if(res.code) {
  14. localStorage.token = res.token; // token 保存到本地存储
  15. alert('登录成功');
  16. this.$router.replace('/home');
  17. } else {
  18. alert('账号或密码错误,登录失败。')
  19. }
  20. }
  21. }
  22. }

二、判断是否有 token

1、设置前置导航守卫

在路由配置文件中,找到需要登录才能访问的页面,添加对应的导航守卫:

  1. const routes = [
  2. {
  3. path: '/home',
  4. component: HomeView,
  5. // 首页的前置导航守卫
  6. beforeEnter: (to, from, next) => {
  7. }
  8. }
  9. ]

2、判断本地是否有 token

  1. const routes = [
  2. {
  3. path: '/home',
  4. component: HomeView,
  5. // 首页的前置导航守卫
  6. beforeEnter: (to, from, next) => {
  7. const token = localStorage.token;
  8. if(token) {
  9. // 本地有 token
  10. } else {
  11. alert('你还未登录,请先登录');
  12. next('/login')
  13. }
  14. }
  15. }
  16. ]

三、判断 token 是否过期

前端无法判断 token 是否过期,只能通过一个请求将 token 添加到请求头中,发送给后端,让后端来验证 token 是否有效。

  1. if(token) {
  2. // 本地有 token
  3. const res = await api.users.getInfo(); // 发送“获取用户信息”的请求
  4. console.log(res);
  5. } else {
  6. alert('你还未登录,请先登录');
  7. next('/login')
  8. }

token 是通过请求头发送给后端的,不需要在请求中传参。

1、统一处理请求头

找到 axios 的公共配置文件 utils/request.js,设置请求拦截器:

  1. // 请求拦截器
  2. axios.interceptors.request.use(config => {
  3. const token = localStorage.token;
  4. if (token) {
  5. config.headers.Authorization = token;
  6. }
  7. return config;
  8. });

四、保存用户信息

将导航守卫中获取到的用户信息,保存到主仓库中。

1、设置用户初始值

我们需要先在主仓库中设置用户信息的初始值,以及修改用户信息的方法:

  1. export default new Vuex.Store({
  2. state: {
  3. userInfo: null
  4. },
  5. mutations: {
  6. SET_USER_INFO(state, payload) {
  7. state.userInfo = payload;
  8. }
  9. }
  10. })

2、保存用户信息

在路由配置文件中,引入仓库对象,然后调用方法来保存用户信息到主仓库:

  1. import store from '@/store'
  2. //...
  3. const routes = [
  4. {
  5. path: '/home',
  6. component: HomeView,
  7. beforeEnter: async (to, from, next) => {
  8. const token = localStorage.getItem('token');
  9. if (token) {
  10. // 发送请求验证token是否有效
  11. const res = await api.users.getInfo();
  12. if (res && res.code) {
  13. store.commit('SET_USER_INFO', res.data);
  14. }
  15. next();
  16. } else {
  17. alert('请先登录');
  18. next('/login');
  19. }
  20. },
  21. }
  22. ]

五、渲染用户信息

在需要渲染用户信息的组件中,获取到仓库中的用户信息,渲染即可。

  1. <p>欢迎你,{{ $store.state.userInfo.username }}</p>

六、处理 token 过期报错

找到 axios 的公共配置文件 utils/request.js,在相应拦截器中处理报错信息:

  1. // 响应拦截器
  2. axios.interceptors.response.use(res => res.data, error => {
  3. if (error && error.response && error.response.status) {
  4. if (error.response.status == 401) {
  5. alert('登录状态已过期,请重新登录。');
  6. router.replace('/login');
  7. return;
  8. }
  9. }
  10. // 程序出现了报错,但不是 401 的错
  11. return Promise.reject(error);
  12. });