SpringBoot JWT
admin
2024-03-02 14:39:57

JWT是一种鉴权机制,实现前后端分离登陆和权限的一种解决方式,用户在登陆之后后端生成token传到前端,以后每次的请求都携带着token到后端验证,如果过期或者失效就要求重新登陆。
具体详情请看:https://blog.csdn.net/weixin_53312997/article/details/126938201

后端如何实现token

首先导个依赖

        com.auth0java-jwt3.4.0com.alibabafastjson1.2.78

其次建立一个jwt工具类

import com.alibaba.fastjson.JSON;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;import java.util.Base64;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;/*** create by fzg* 2021/10/12 9:41*/public class JwtUtil {private static String TOKEN = "token!Q@W3e4r";/*** 生成token * @param map //传入payload * @return 返回token */public static String getToken(Map map){JWTCreator.Builder builder = JWT.create();map.forEach((k,v)->{ builder.withClaim(k,v); });Calendar instance = Calendar.getInstance();instance.add(Calendar.HOUR,24*3);builder.withExpiresAt(instance.getTime());return builder.sign(Algorithm.HMAC256(TOKEN)).toString();}/**7.整合springboot * 验证token * @param token * @return* @return*/public static void verify(String token){JWT.require(Algorithm.HMAC256(TOKEN)).build().verify(token);}/*** 获取token中payload * @param token * @return */public static DecodedJWT getToken(String token){return JWT.require(Algorithm.HMAC256(TOKEN)).build().verify(token);}// token 获取idpublic static Integer getTokenId(String token){DecodedJWT untoken = JwtUtil.getToken(token);String payload = untoken.getPayload();Base64.Decoder decoder = Base64.getDecoder();byte[] bytes = decoder.decode(payload);//System.out.println("BASE64解密:" + new String(bytes));String str = new String(bytes);HashMap hashMap = JSON.parseObject(str, HashMap.class);Integer aid = Integer.parseInt(hashMap.get("aid").toString());return aid;}// 解密tokenpublic static String getClaim(String token, String key) {DecodedJWT decodedJWT = JWT.decode(token);Claim value = decodedJWT.getClaim(key);return value.asString();}
}

请求拦截器

import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fzg.common.tool.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;/*** create by fzg* 2021/10/12 10:47*/public class MyInterceptor implements HandlerInterceptor {@Autowiredprivate JwtUtil jwtUtil;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 从前端请求中获取tokenString token = request.getHeader("token");Map map = new HashMap<>();if (token == null){map.put("state",false);map.put("msg","token为空");}else {try {JwtUtil.verify(token);Integer aid = Integer.parseInt(JwtUtil.getClaim(token,"aid"));request.setAttribute("aid",aid);return true;}catch (TokenExpiredException e){map.put("state",false);map.put("msg","token已过期!");}catch (SignatureVerificationException e){map.put("state",false);map.put("msg","签名错误!");}catch (AlgorithmMismatchException e){map.put("state",false);map.put("msg","加密算法不匹配");}catch (Exception e){map.put("state",false);map.put("msg","无效token!");}}String json = new ObjectMapper().writeValueAsString(map);response.setContentType("application/json;charset=UTF-8");response.getWriter().println(json);return false;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {HandlerInterceptor.super.afterCompletion(request, response, handler, ex);}
}

拦截配置

拦截所有请求,除了用户登陆和注册,其他都需要经过MyInterceptor请求拦截器

import com.fzg.common.interceptor.MyInterceptor;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** create by fzg* 2021/10/12 12:02*/@Component
public class InceptorConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/user/register").excludePathPatterns("/user/login");}
}

跨域配置

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** create by fzg* 2021/10/9 10:57*/@Configuration
public class CrosConfig implements WebMvcConfigurer {@Beanpublic CorsFilter corsFilter() {CorsConfiguration config = new CorsConfiguration();config.addAllowedOrigin("*");config.addAllowedMethod("*");config.addAllowedHeader("*");config.addExposedHeader("token");UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();configSource.registerCorsConfiguration("/**", config);return new CorsFilter(configSource);}
}

用户登陆成功后后端将token传到前端

HashMap map = new HashMap<>();
map.put("aid",user.getAid().toString());
String token = JwtUtil.getToken(map);

前端的所有请求携带token

//引入axios,进行二次封装
import axios from 'axios'const requests = axios.create({// 配置对象//基础路径,发送请求的时候,路径当中会出现apibaseURL: 'http://localhost:8001',// baseURL: 'http://43.142.195.65:8001',//代表请求超时的时间5秒timeout: 5000,
});export default requests;
// 前端拿到之后存储到localStorage,
// 发送请求的时候再携带token
export const requestMethodName = (param) => requests({url: `/blog/userCancelCollectBlog?blogAid=${param}`,method: 'post',headers: {token: localStorage.getItem('token'),}
});// get请求(例子)
export const queryUserConcernList = (data) => requests({url: `/user/queryUserConcernList`,method: 'get',params: data,headers: {token: localStorage.getItem('token'),}
});// post请求例子
export const sendMessageToChatObject = (params) => requests({url: `/chat/sendMessageToChatObject`,method: 'post',data: params,headers: {token: localStorage.getItem('token'),}
});

相关内容

热门资讯

上海旅游节大巡游花车阵容抢先看... 2026上海旅游节大巡游9月12日外滩启幕,21辆全新主题花车携手21支境内外表演方队联袂登场,邀你...
原创 8... 上周门诊来了位 62 岁的张阿姨,得糖尿病快五年了,平时管嘴特别严,糖果、点心、甜饮料一概不碰,连水...
原创 餐... 2026年9月8日晚,南京浦口区泰冯路29号,墨语江南·阿婆菜餐厅户外帐篷里,灯火温润,其间还天降喜...
原创 它... 人到中年肝肾精血慢慢耗损,容易腰膝酸软、头晕眼花、精神疲惫。黄精性平,擅长补肝肾、益精血,搭配不同食...
同样卖奶茶,为何古茗赚了15亿... 出品/联商专栏 撰文/老刀 编辑/蔡建桢 今年上半年,蜜雪、古茗、霸王茶姬、茶百道、沪上阿姨全部盈利...