🍁 作者:知识浅谈,CSDN签约讲师,CSDN博客专家,华为云云享专家,阿里云专家博主 📌 擅长领域:全栈工程师、爬虫、ACM算法
视频教程:SpringSecurity集成JWT认证授权保姆级教程-数据准备
上一篇:SpringSecurity集成JWT实现后端认证授权保姆级教程-数据准备篇
下一篇:SpringSecurity集成JWT实现后端认证授权保姆级教程-认证配置篇
🤞在上一节数据准备好之后,这节主要准备一下各种工具类
🤞
🎈创建常用常量和Result返回类
OtherConstants.java
package com.example.demo.common.constants;
/**
-
@author: zsqt
-
Package: com.zsqt.security.constants
-
@date: 2024/1/3 16:52
-
@Description:
@version: 1.0
*/
public class OtherConstants {public static final String AUTH_TOKEN = "Authorization"; //TOKEN对应的KEY
public static final Integer TOKEN_SITE = 7; //TOKEN前边的Bearer 字符串 共有7个字符
public static final String USER_PREFIX = "USER:"; //用户前缀
}
Result.java
package com.example.demo.common.Vo;
import lombok.Data;
@Data
public class Result<T> {
private Integer code;
private String msg;
private T data;
public Result() {
}
public Result(T data) {
this.data = data;
}
/**
- 成功返回结果
- @return
/
public static Result success() {
Result result = new Result<>();
result.setCode(200);
result.setMsg("成功");
return result;
}
/* - 成功返回结果
- @param data
- @return
- @param <T>
/
public static <T> Result<T> success(T data) {
Result<T> result = new Result<>(data);
result.setCode(200);
result.setMsg("成功");
return result;
}
/* - 失败返回结果
- @param code
- @param msg
- @return
/
public static Result error(Integer code, String msg) {
Result result = new Result();
result.setCode(code);
result.setMsg(msg);
return result;
}
/* - 失败返回结果
- @param msg
@return
*/
public static Result error500(String msg) {
Result result = new Result();
result.setCode(500);
result.setMsg(msg);
return result;
}
}
🎈跨域配置类
CorsConfig.class
package com.example.demo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class CorsConfig implements WebMvcConfigurer {@Override public void addCorsMappings(CorsRegistry registry) { // 设置允许跨域的路径 registry.addMapping("/**") // 设置允许跨域请求的域名 .allowedOriginPatterns("*") // 是否允许cookie .allowCredentials(true) // 设置允许的请求方式 .allowedMethods("GET", "POST", "DELETE", "PUT") // 设置允许的header属性 .allowedHeaders("*") // 跨域允许时间 .maxAge(3600); }
}
🎈Swagger配置类
package com.example.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
-
@author: zsqt
-
Package: com.zsqt.security.config
-
@date: 2024/1/4 14:29
-
@Description:
@version: 1.0
/
@Configuration
@EnableSwagger2
public class SwaggerConfiguration {
@Bean
public Docket createDocApi() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build()
.groupName("接口文档")
.pathMapping("/")
.apiInfo(DocApi());
}
/*构建 api文档的详细信息函数,注意这里的注解引用的是哪个
/
private ApiInfo DocApi() {
return new ApiInfoBuilder()
//页面标题
.title("接口测试工具")
//创建人
.contact(new Contact("", "", ""))
//版本号
.version("1.0")
//描述
.description("接口测试工具")
.build();
}
}
🎈JwtUtil配置类
JwtUtil.java
package com.example.demo.utils;
/*
@author: zsqt
Package: com.zsqt.security.utils
@date: 2024/1/3 16:52
@Description:
@version: 1.0
/
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.example.demo.domain.CustUser;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.;
import static com.example.demo.common.constants.OtherConstants.*;
@Component
@RequiredArgsConstructor
public class JwtUtil {
private static final String key = "ims_test"; // 密钥
private final RedisTemplate redisTemplate; //
/**
- 创建jwt
- @param details 用户登陆信息
- @return String
*/
public String createJwt(CustUser details) {
Algorithm algorithm = Algorithm.HMAC256(key);
return JWT.create()
.withJWTId(UUID.randomUUID().toString())
.withClaim("user",details.getId()) //把用户id存入token中
.withExpiresAt(expireTime())
.withIssuedAt(new Date())// 签发时间
.sign(algorithm);
}
/**
- 解析token
- @param authToken token
- @return DecodedJWT
*/
public DecodedJWT resolveJwt(String authToken) {
String token = convertToken(authToken);
if (token == null)
return null;
Algorithm algorithm = Algorithm.HMAC256(key);
JWTVerifier jwtVerifier = JWT.require(algorithm).build();
try {
DecodedJWT verify = jwtVerifier.verify(token); // 验证token
Date expiresAt = verify.getExpiresAt(); // token过期时间
return new Date().after(expiresAt) ? null : verify; // 判断是否过期
} catch (JWTVerificationException jwtVerificationException) {
return null;
}
}
/**
- 检查用户在redis中是否存在
- @param user
- @return
*/
public boolean checkRedis(CustUser user) {
if(redisTemplate.opsForValue().get(USER_PREFIX + user.getId()) == null){
return false;
}else{
return true;
}
}
/**
- 根据解析后的token获取用户信息
*/
public CustUser toUser(DecodedJWT jwt) {
Integer uid;
try {
Map<String, Claim> claims = jwt.getClaims();
uid = claims.get("user").asInt();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("token非法");
}
CustUser user = (CustUser) redisTemplate.opsForValue().get(USER_PREFIX +uid);
if(Objects.isNull(user)){
throw new RuntimeException("用户未登录");
}
return user;
}
/**
- 在请求头信息中获取token 去掉对应的前缀
*/
private String convertToken(String authToken) {
if (!StringUtils.hasText(authToken) || !authToken.startsWith("Bearer "))
return null;
return authToken.substring(TOKEN_SITE);// 截取token 因为token前面有Bearer空格
}
/**
- 设置token过期时间
@return
*/
private Date expireTime() {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MINUTE, 30);
return calendar.getTime();
}
}
测试一下swagger文档
http://localhost:8080/doc.html#/home
到这工具类准备就绪,接下来就要进行各种security认证配置了。
🍚总结
大功告成,撒花致谢🎆🎇🌟,关注我不迷路,带你起飞带你富。