SpringBoot整合JWT+Vue

朴灿烈づ我的快乐病毒、 2024-04-01 13:14 129阅读 0赞
  • 引入pom

    1. <dependency>
    2. <groupId>com.auth0</groupId>
    3. <artifactId>java-jwt</artifactId>
    4. <version>3.10.0</version>
    5. </dependency>
  • 编写工具类

    import com.auth0.jwt.JWT;
    import com.auth0.jwt.JWTCreator;
    import com.auth0.jwt.algorithms.Algorithm;
    import com.auth0.jwt.interfaces.DecodedJWT;

    import java.util.Calendar;
    import java.util.Map;

    /**

    • @Description: JWT工具类
      */
      public class JWTUtils {

      //秘钥
      private static final String SIGNATURE = “aef7aaf174fa0143ce765a7efd869313”;
      //过期时间为1天
      public static final Integer EXPIRATION_TIME= 1 24 60 * 60;

  1. /**
  2. * 生成token
  3. * @param payload token需要携带的信息
  4. * @return token字符串
  5. */
  6. public static String getToken(Map<String,String> payload){
  7. // 指定token过期时间为1天
  8. Calendar calendar = Calendar.getInstance();
  9. calendar.add(Calendar.SECOND, EXPIRATION_TIME);
  10. JWTCreator.Builder builder = JWT.create();
  11. // 构建payload
  12. payload.forEach((k,v) -> builder.withClaim(k,v));
  13. // 指定过期时间和签名算法
  14. return builder.withExpiresAt(calendar.getTime()).sign(Algorithm.HMAC256(SIGNATURE));
  15. }
  16. /**
  17. * 验证token
  18. * @param token
  19. */
  20. public static void verify(String token){
  21. JWT.require(Algorithm.HMAC256(SIGNATURE)).build().verify(token);
  22. }
  23. /**
  24. * 获取token中payload
  25. * @param token
  26. * @return
  27. */
  28. public static DecodedJWT getPayload(String token){
  29. return JWT.require(Algorithm.HMAC256(SIGNATURE)).build().verify(token);
  30. }
  31. }
  32. /**
  33. * 状态码枚举
  34. */
  35. public enum CodeEnum {
  36. /**操作成功**/
  37. SUCCESS(200,"操作成功"),
  38. /**服务调用异常**/
  39. SERVICE_CALL_EXCEPTION(400,"服务调用异常"),
  40. /**操作失败**/
  41. ERROR(500,"操作失败"),
  42. /**参数不合法**/
  43. ILLEGAL_PARAMETER(5001,"参数不合法"),
  44. /**验证码已失效**/
  45. VERIFICATION_CODE_FAILURE(5002,"验证码已失效"),
  46. /**用户昵称重复**/
  47. DUPLICATE_NICKNAME(5003,"用户昵称重复"),
  48. /**用户名或密码错误**/
  49. LOGIN_FAILED(5004,"用户名或密码错误"),
  50. /**文件上传失败**/
  51. FILE_UPLOAD_FAILED(5005,"文件上传失败"),
  52. /**资源不存在*/
  53. RESOURCE_DOES_NOT_EXIST(5006,"资源不存在"),
  54. /**无效签名**/
  55. JWT_INVALID(2001,"无效签名"),
  56. /**token过期**/
  57. JWT_OVERDUE(2002,"token过期"),
  58. /**token算法不一致**/
  59. JWT_ALGORITHM_INCONSISTENCY(2003,"token算法不一致"),
  60. /**token失效**/
  61. JWT_LOSE_EFFECT(2004,"token失效"),
  62. /**非法请求**/
  63. ILLEGAL_REQUEST(2005,"非法请求,请求来源不合法");
  64. /**
  65. * 自定义状态码
  66. **/
  67. private Integer code;
  68. /**自定义描述**/
  69. private String message;
  70. CodeEnum(Integer code, String message){
  71. this.code = code;
  72. this.message = message;
  73. }
  74. public Integer getCode() {
  75. return code;
  76. }
  77. public String getMessage() {
  78. return message;
  79. }
  80. }
  81. import lombok.AllArgsConstructor;
  82. import lombok.Data;
  83. import lombok.NoArgsConstructor;
  84. /**
  85. * 请求信息类,用于返回请求是否成功
  86. * @param <T>
  87. */
  88. @Data
  89. @AllArgsConstructor
  90. @NoArgsConstructor
  91. public class CommonResult<T>{
  92. /**
  93. * 响应状态码
  94. */
  95. private int code;
  96. /**
  97. * 响应结果描述
  98. */
  99. private String message;
  100. /**
  101. * 返回的数据
  102. */
  103. private T data;
  104. /**
  105. * 成功返回
  106. * @param data
  107. * @param <T>
  108. * @return
  109. */
  110. public static <T> CommonResult<T> success(T data) {
  111. CommonResult<T> response= new CommonResult<>();
  112. response.setCode(CodeEnum.SUCCESS.getCode());
  113. response.setMessage(CodeEnum.SUCCESS.getMessage());
  114. response.setData(data);
  115. return response;
  116. }
  117. /**
  118. * 失败返回,自定义code
  119. * @param code
  120. * @param message
  121. * @param <T>
  122. * @return
  123. */
  124. public static <T> CommonResult<T> fail(Integer code, String message) {
  125. CommonResult<T> response = new CommonResult<>();
  126. response.setCode(code);
  127. response.setMessage(message);
  128. return response;
  129. }
  130. /**
  131. * 失败返回
  132. * @param codeEnum
  133. * @param <T>
  134. * @return
  135. */
  136. public static <T> CommonResult<T> fail(CodeEnum codeEnum) {
  137. CommonResult<T> response = new CommonResult<>();
  138. response.setCode(codeEnum.getCode());
  139. response.setMessage(codeEnum.getMessage());
  140. return response;
  141. }
  142. /**
  143. * 失败返回
  144. * @param message
  145. * @param <T>
  146. * @return
  147. */
  148. public static <T> CommonResult<T> fail(String message) {
  149. CommonResult<T> response = new CommonResult<>();
  150. response.setCode(CodeEnum.ERROR.getCode());
  151. response.setMessage(message);
  152. return response;
  153. }
  154. }
  • 编写请求拦截器

    import cn.hutool.core.util.StrUtil;
    import com.auth0.jwt.exceptions.AlgorithmMismatchException;
    import com.auth0.jwt.exceptions.SignatureVerificationException;
    import com.auth0.jwt.exceptions.TokenExpiredException;
    import com.example.vehicleinformationsystem.bean.CodeEnum;
    import com.example.vehicleinformationsystem.bean.CommonResult;
    import com.example.vehicleinformationsystem.util.JWTUtils;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import org.springframework.stereotype.Component;
    import org.springframework.web.servlet.HandlerInterceptor;

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    /**

    • @Description: jwt拦截器
      */
      @Component
      public class JWTInterceptor implements HandlerInterceptor {

      @Override
      public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

      1. //获取请求头中存放的令牌token
      2. String token = request.getHeader("Authorization");
      3. CommonResult<CodeEnum> result=new CommonResult();
      4. try {
      5. if(StrUtil.isNotBlank(token)){
      6. //验证令牌
      7. JWTUtils.verify(token);
      8. return true;
      9. }else{
      10. result.setCode(CodeEnum.JWT_INVALID.getCode());
      11. result.setMessage(CodeEnum.JWT_INVALID.getMessage());
      12. }
      13. } catch (SignatureVerificationException e) {
      14. e.printStackTrace();
      15. result.setCode(CodeEnum.JWT_INVALID.getCode());
      16. result.setMessage(CodeEnum.JWT_INVALID.getMessage());
      17. } catch (AlgorithmMismatchException e) {
      18. e.printStackTrace();
      19. result.setCode(CodeEnum.JWT_ALGORITHM_INCONSISTENCY.getCode());
      20. result.setMessage(CodeEnum.JWT_ALGORITHM_INCONSISTENCY.getMessage());
      21. } catch (TokenExpiredException e) {
      22. e.printStackTrace();
      23. result.setCode(CodeEnum.JWT_OVERDUE.getCode());
      24. result.setMessage(CodeEnum.JWT_OVERDUE.getMessage());
      25. } catch (Exception e) {
      26. e.printStackTrace();
      27. result.setCode(CodeEnum.JWT_OVERDUE.getCode());
      28. result.setMessage(CodeEnum.JWT_OVERDUE.getMessage());
      29. }
  1. //将map转为json,返回给前端
  2. String json = new ObjectMapper().writeValueAsString(result);
  3. response.setContentType("application/json;charset=utf-8");
  4. response.getWriter().print(json);
  5. return false;
  6. }
  7. }
  • 注册拦截器

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

    /**

    • @Description: 注册拦截器
      */

    @Configuration
    public class InterceptorConfig implements WebMvcConfigurer {

    1. @Autowired
    2. private JWTInterceptor jwtInterceptor;
    3. @Override
    4. public void addInterceptors(InterceptorRegistry registry) {
    5. registry.addInterceptor(jwtInterceptor)
    6. //拦截所有请求
    7. .addPathPatterns("/**")
    8. //不需要拦截的请求
    9. .excludePathPatterns("/system/login","/system/addUser");
    10. }

    }

  • 测试
    1.不携带token
    在这里插入图片描述
    返回结果:
    在这里插入图片描述
    2.携带token

在这里插入图片描述

  • 整合Vue

1.解决跨域问题

  1. import org.springframework.context.annotation.Bean;
  2. import org.springframework.context.annotation.Configuration;
  3. import org.springframework.web.cors.CorsConfiguration;
  4. import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
  5. import org.springframework.web.filter.CorsFilter;
  6. /**
  7. 解决跨域
  8. */
  9. @Configuration
  10. public class GlobalCorsConfig {
  11. @Bean
  12. public CorsFilter corsFilter() {
  13. //1.添加CORS配置信息
  14. CorsConfiguration config = new CorsConfiguration();
  15. config.addAllowedOriginPattern("*");
  16. //2) 是否发送Cookie信息
  17. config.setAllowCredentials(true);
  18. //3) 允许的请求方式
  19. config.addAllowedMethod("OPTIONS");
  20. config.addAllowedMethod("HEAD");
  21. config.addAllowedMethod("GET");
  22. config.addAllowedMethod("PUT");
  23. config.addAllowedMethod("POST");
  24. config.addAllowedMethod("DELETE");
  25. config.addAllowedMethod("PATCH");
  26. // 4)允许的头信息
  27. config.addAllowedHeader("*");
  28. // 4)有效时间
  29. config.setMaxAge(3600L);
  30. //2.添加映射路径,我们拦截一切请求
  31. UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
  32. configSource.registerCorsConfiguration("/**", config);
  33. //3.返回新的CorsFilter.
  34. return new CorsFilter(configSource);
  35. }
  36. }

2.登录成功返回token

  1. /**
  2. * 登录
  3. *
  4. * @param userInfo
  5. * @return
  6. */
  7. @PostMapping(value = "/login")
  8. public CommonResult<Map<String,Object>> login(@RequestBody Map<String,Object> userInfo) {
  9. if(userInfo!=null){
  10. if("admin".equals(userInfo.get("nickName"))&&"admin".equals(userInfo.get("password"))){
  11. //设置token需要返回的信息
  12. Map<String,String> tokenMap=new HashMap<>();
  13. tokenMap.put("id","111");
  14. tokenMap.put("nickName",userInfo.get("nickName"));
  15. result.put("token",JWTUtils.getToken(tokenMap));
  16. return CommonResult.success(result);
  17. }
  18. }
  19. return CommonResult.fail("用户昵称或密码错误");
  20. }

3.Vue将登录成功后接收到的token存储在浏览器

  1. //登录请求
  2. login(this.param).then(res => {
  3. console.log("登录请求结果--》》", res);
  4. //判断是否登录成功
  5. if (res.code == 200) {
  6. this.$message.success('登录成功');
  7. localStorage.setItem('token', res.data.token);
  8. } else {
  9. this.$message.error('用户昵称或密码错误');
  10. }
  11. });

4.每次请求时,携带token(此处可以在vue编写一个请求前置拦截器,这样携带token这个步骤就可以降低冗余,此处略)

  1. /**
  2. *删除用户信息
  3. * @param {*} param
  4. */
  5. export const deleteUser = param => {
  6. return request({
  7. url: '/system/deleteUser/'+ param,
  8. method: 'GET',
  9. headers:{
  10. //向headers中添加token
  11. Authorization:localStorage.getItem("token")
  12. }
  13. });
  14. };

发表评论

表情:
评论列表 (有 0 条评论,129人围观)

还没有评论,来说两句吧...

相关阅读