fix: 注销方法问题修复,validation移至common-web

This commit is contained in:
haoxr 2022-11-10 07:27:59 +08:00
parent 9d397c188f
commit 98a05349e7
17 changed files with 99 additions and 71 deletions

View File

@ -1,7 +1,7 @@
package com.youlai.mall.ums.pojo.form; package com.youlai.mall.ums.pojo.form;
import com.youlai.common.constraint.CheckCityValid; import com.youlai.common.web.constraint.CheckCityValid;
import com.youlai.common.constraint.CityType; import com.youlai.common.web.constraint.CityType;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;

View File

@ -1,11 +1,11 @@
package com.youlai.auth.controller; package com.youlai.auth.controller;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import com.youlai.auth.util.RequestUtils; import com.youlai.auth.util.RequestUtils;
import com.youlai.common.constant.SecurityConstants; import com.youlai.common.constant.SecurityConstants;
import com.youlai.common.result.Result; import com.youlai.common.result.Result;
import com.youlai.common.web.util.JwtUtils;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiImplicitParams;
@ -29,7 +29,6 @@ import java.util.concurrent.TimeUnit;
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j @Slf4j
public class AuthController { public class AuthController {
private final TokenEndpoint tokenEndpoint; private final TokenEndpoint tokenEndpoint;
private final RedisTemplate redisTemplate; private final RedisTemplate redisTemplate;
@ -75,16 +74,22 @@ public class AuthController {
@ApiOperation(value = "注销") @ApiOperation(value = "注销")
@DeleteMapping("/logout") @DeleteMapping("/logout")
public Result logout() { public Result logout() {
JSONObject payload = JwtUtils.getJwtPayload(); String payload = RequestUtils.getJwtPayload();
String jti = payload.getStr("jti"); // JWT唯一标识
Long expireTime = payload.getLong("exp"); // JWT过期时间戳(单位) if (StrUtil.isNotBlank(payload)) {
if (expireTime != null) { JSONObject entries = JSONUtil.parseObj(payload);
long currentTime = System.currentTimeMillis() / 1000;// 当前时间单位 if (entries != null) {
if (expireTime > currentTime) { // token未过期添加至缓存作为黑名单限制访问缓存时间为token过期剩余时间 String jti = entries.getStr("jti"); // JWT唯一标识
redisTemplate.opsForValue().set(SecurityConstants.TOKEN_BLACKLIST_PREFIX + jti, null, (expireTime - currentTime), TimeUnit.SECONDS); Long expireTime = entries.getLong("exp"); // JWT过期时间戳(单位)
if (expireTime != null) {
long currentTime = System.currentTimeMillis() / 1000;// 当前时间单位
if (expireTime > currentTime) { // token未过期添加至缓存作为黑名单限制访问缓存时间为token过期剩余时间
redisTemplate.opsForValue().set(SecurityConstants.BLACKLIST_TOKEN_PREFIX + jti, null, (expireTime - currentTime), TimeUnit.SECONDS);
}
} else { // token 永不过期则永久加入黑名单
redisTemplate.opsForValue().set(SecurityConstants.BLACKLIST_TOKEN_PREFIX + jti, null);
}
} }
} else { // token 永不过期则永久加入黑名单
redisTemplate.opsForValue().set(SecurityConstants.TOKEN_BLACKLIST_PREFIX + jti, null);
} }
return Result.success("注销成功"); return Result.success("注销成功");
} }

View File

@ -1,13 +1,17 @@
package com.youlai.auth.util; package com.youlai.auth.util;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.nimbusds.jose.JWSObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.util.Base64; import java.util.Base64;
@Slf4j
public class RequestUtils { public class RequestUtils {
/** /**
@ -38,5 +42,27 @@ public class RequestUtils {
} }
return clientId; return clientId;
} }
/**
* 获取JWT Payload
*
* @return
*/
public static String getJwtPayload() {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String payload = null;
String authorization = request.getHeader("Authorization");
if (StrUtil.isNotBlank(authorization) && StrUtil.startWithIgnoreCase(authorization, "Bearer ")) {
authorization = StrUtil.replaceIgnoreCase(authorization, "Bearer ", "");
try {
payload = JWSObject.parse(authorization).getPayload().toString();
} catch (ParseException e) {
log.error(e.getMessage());
}
}
return payload;
}
} }

View File

@ -38,10 +38,7 @@
<artifactId>spring-data-redis</artifactId> <artifactId>spring-data-redis</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies> </dependencies>

View File

@ -3,9 +3,9 @@ package com.youlai.common.constant;
public interface SecurityConstants { public interface SecurityConstants {
/** /**
* 黑名单token前缀 * 黑名单TOKEN Key前缀
*/ */
String TOKEN_BLACKLIST_PREFIX = "auth:token:blacklist:"; String BLACKLIST_TOKEN_PREFIX = "AUTH:BLACKLIST_TOKEN:";
/** /**
* 验证码key前缀 * 验证码key前缀

View File

@ -74,6 +74,11 @@
<artifactId>mapstruct-processor</artifactId> <artifactId>mapstruct-processor</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -0,0 +1,39 @@
package com.youlai.common.web.config;
import org.hibernate.validator.HibernateValidator;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.beanvalidation.SpringConstraintValidatorFactory;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
/**
* 运行时入参校验配置
*
* @author haoxr
* @date 2022/11/10
*/
@Configuration
public class ValidationConfig {
/**
* 自定义validator实现快速失败
*
* @param autowireCapableBeanFactory
* @return
*/
@Bean
public Validator validator( AutowireCapableBeanFactory autowireCapableBeanFactory) {
ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
.configure()
.failFast(true) // failFast=true 不校验所有参数只要出现校验失败情况直接返回不再进行后续参数校验
.constraintValidatorFactory(new SpringConstraintValidatorFactory(autowireCapableBeanFactory))
.buildValidatorFactory();
return validatorFactory.getValidator();
}
}

View File

@ -43,14 +43,4 @@ public class WebMvcConfig implements WebMvcConfigurer {
converters.add(0, jackson2HttpMessageConverter); converters.add(0, jackson2HttpMessageConverter);
} }
@Bean
public Validator validator(final AutowireCapableBeanFactory autowireCapableBeanFactory) {
ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
.configure()
.failFast(true) // failFast=true 不校验所有参数只要出现校验失败情况直接返回不再进行后续参数校验
.constraintValidatorFactory(new SpringConstraintValidatorFactory(autowireCapableBeanFactory))
.buildValidatorFactory();
return validatorFactory.getValidator();
}
} }

View File

@ -1,4 +1,4 @@
package com.youlai.common.constraint; package com.youlai.common.web.constraint;
import javax.validation.Constraint; import javax.validation.Constraint;
import javax.validation.Payload; import javax.validation.Payload;

View File

@ -1,4 +1,4 @@
package com.youlai.common.constraint; package com.youlai.common.web.constraint;
import lombok.Data; import lombok.Data;

View File

@ -1,4 +1,4 @@
package com.youlai.common.constraint; package com.youlai.common.web.constraint;
/** /**
* @author Gadfly * @author Gadfly

View File

@ -1,4 +1,4 @@
package com.youlai.common.constraint; package com.youlai.common.web.constraint;
import cn.hutool.core.io.IoUtil; import cn.hutool.core.io.IoUtil;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;

View File

@ -1,33 +0,0 @@
package com.youlai.common.web.util;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.youlai.common.constant.SecurityConstants;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
/**
* JWT工具类
*
* @author haoxr
* @date 2022/2/5
*/
@Slf4j
public class JwtUtils {
@SneakyThrows
public static JSONObject getJwtPayload() {
JSONObject jsonObject = null;
String payload = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getHeader("payload");
if (StrUtil.isNotBlank(payload)) {
jsonObject = JSONUtil.parseObj(URLDecoder.decode(payload, StandardCharsets.UTF_8.name()));
}
return jsonObject;
}
}

View File

@ -1,4 +0,0 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.youlai.common.web.config.WebMvcConfig,\
com.youlai.common.web.config.FeignConfig,\
com.youlai.common.web.exception.GlobalExceptionHandler

View File

@ -0,0 +1,3 @@
com.youlai.common.web.config.WebMvcConfig
com.youlai.common.web.config.FeignConfig
com.youlai.common.web.exception.GlobalExceptionHandler