前后端分离-Axios拦截器传递Token

JWT

  • 生成token拦截器(springboot拦截器)
package com.coderitl.file.intercepter;

import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.coderitl.file.utils.JWTUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class JWTInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Map<String, Object> map = new HashMap<>();
        // 获取请求头中的 map
        String token = request.getHeader("Authorization");
        log.debug("token: {}",token);
        try {
            // 验证令牌
            JWTUtils.verify(token);
            // 放行请求
            return true;
        } catch (SignatureVerificationException e) {
            e.printStackTrace();
            map.put("msg", "无效签名!");
        } catch (TokenExpiredException e) {
            e.printStackTrace();
            map.put("msg", "token已过期!");
        } catch (AlgorithmMismatchException e) {
            e.printStackTrace();
            map.put("msg", "token算法不一致!");
        } catch (Exception e) {
            e.printStackTrace();
            // TODO: 消息未响应在页面
            map.put("msg", "token无效!");
        }
        // 设置状态
        map.put("status", false);
        // 将 map 转换为 json jackson(@ResponseBody)
        String json = new ObjectMapper().writeValueAsString(map);
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write(json);
        return false;
    }
}

  • 字段传递问题

    Authorization
  • axios传递字段

    axios传递字段
  • api位置问题

    • 修改前

      api位置问题
    • 修改后

      api位置
  • 使用axios拦截器对请求添加token所需字段

    使用axios拦截器对请求添加token所需字段
  • devServer配置不生效问题

    import axios from 'axios'
    
    let baseURL = '/'
    if (process.env.NODE_ENV === 'production') {
        // 后端接口地址
        baseURL = 'http://localhost:8081/' 
    }
    
    export function request(config) {
        const instance = axios.create({
            baseURL,
            timeout: 5000,
        })
        // 未登录时 token 是空的
        const token = window.localStorage.getItem('token')
    
        // 请求拦截器
        instance.interceptors.request.use(
            config => {
                // 每次发送请求之前判断是否存在token,如果存在,则统一在http请求的header都加上token,不用每次请求都手动添加了
                if (token) {
                    // 设置统一的 request header Authorization
                    config.headers.Authorization = token
                }
                return config
            },
            err => {
                return Promise.reject(err)
            }
        )
    
        // http response 服务器响应拦截器,这里拦截401错误,并重新跳入登页重新获取token
        instance.interceptors.response.use(
            response => {
                return response
            },
            error => {
                if (error.response) {
                    switch (error.response.status) {
                        case 401:
                            // 这里写清除token的代码
                            router.replace({
                                path: 'login',
                                query: { redirect: router.currentRoute.fullPath }, // 登录成功后跳入浏览的当前页面
                            })
                    }
                }
                return Promise.reject(error.response.data)
            }
        )
        // 发送真正的网络请求(Promise)
        return instance(config)
    }
    
    
     
    devServer: {
            // 配置服务器代理
            proxy: {
                '/api': {
                    // 匹配访问路径中含有 '/api' 的路径
                    target: 'http://localhost:8081/', // 目标地址(后端接口)
                    changeOrigin: true,
                    ws: true, // 是否开启 webSocket 代理
                    pathRewrite: {
                        // 请求路径重写
                        '^/api': '', //重写请求路径
                    },
                },
            },
        },
    
  • 接口封装

import { request } from '../request'

// 登录
export function loginApi(data) {
    return request({
        url: '/api/user/login',
        method: 'get',
        params: {
            ...data,
        },
    })
}

export function testApi() {
    return request({
        url: '/api/user/test',
        method: 'get',
    })
}

  • 调用接口
// 后期容易维护
import { loginApi, testApi } from '@/network/user/login'

methods: {
        // 登录提交
        submitForm(formName) {
            this.$refs[formName].validate(async valid => {
                if (valid) {
                    let _this = this
                    let param = {
                        userName: _this.ruleForm.userName,
                        password: _this.ruleForm.password,
                    }
                    // 发起 axios 请求
                    const { data: res } = await loginApi(param)
                    // 存储用户信息
                    window.localStorage.setItem(
                        'token',
                        // JSON.stringify() 方法将一个 JavaScript 对象或值转换为 JSON 字符串
                        res.token
                    )
                    // 登录成功后发送 验证 拦截器是否生效
                    testApi().then(res => {
                        console.log(res)
                    })

                    _this.$router.push('/home')
                } else {
                    _this.$message.error('登录失败')
                    return false
                }
            })
        }
    },
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值