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
}
})
}
},