🍁 作者:知识浅谈,CSDN签约讲师,CSDN博客专家,华为云云享专家,阿里云专家博主 📌 擅长领域:全栈工程师、爬虫、ACM算法
🎈创建常用常量和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认证配置了。
🍚总结
大功告成,撒花致谢🎆🎇🌟,关注我不迷路,带你起飞带你富。