fix: 优化移动端校验
This commit is contained in:
@@ -2,22 +2,22 @@ package com.youlai.boot.framework.security.filter;
|
|||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.crypto.digest.DigestUtil;
|
import cn.hutool.crypto.digest.DigestUtil;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import com.youlai.boot.common.result.Result;
|
||||||
import com.youlai.boot.common.result.ResultCode;
|
import com.youlai.boot.common.result.ResultCode;
|
||||||
import com.youlai.boot.common.result.ResponseWriter;
|
|
||||||
import jakarta.servlet.FilterChain;
|
import jakarta.servlet.FilterChain;
|
||||||
import jakarta.servlet.ServletException;
|
import jakarta.servlet.ServletException;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.web.filter.OncePerRequestFilter;
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.SortedMap;
|
import java.util.SortedMap;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 移动设备API签名验证过滤器
|
* 移动设备API签名验证过滤器
|
||||||
@@ -68,20 +68,20 @@ public class MobileApiSignatureFilter extends OncePerRequestFilter {
|
|||||||
// 1. 获取设备标识
|
// 1. 获取设备标识
|
||||||
String deviceId = request.getHeader(HEADER_DEVICE_ID);
|
String deviceId = request.getHeader(HEADER_DEVICE_ID);
|
||||||
if (StrUtil.isBlank(deviceId)) {
|
if (StrUtil.isBlank(deviceId)) {
|
||||||
ResponseWriter.writeSuccess(response, ResultCode.MOBILE_DEVICE_ID_REQUIRED);
|
writeErrorResponse(response, ResultCode.MOBILE_DEVICE_ID_REQUIRED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 获取随机数
|
// 获取随机数
|
||||||
String nonce = request.getHeader(HEADER_NONCE);
|
String nonce = request.getHeader(HEADER_NONCE);
|
||||||
if (StrUtil.isBlank(nonce)) {
|
if (StrUtil.isBlank(nonce)) {
|
||||||
ResponseWriter.writeSuccess(response, ResultCode.MOBILE_NONCE_REQUIRED);
|
writeErrorResponse(response, ResultCode.MOBILE_NONCE_REQUIRED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 获取时间戳
|
// 2. 获取时间戳
|
||||||
String timestampStr = request.getHeader(HEADER_TIMESTAMP);
|
String timestampStr = request.getHeader(HEADER_TIMESTAMP);
|
||||||
if (StrUtil.isBlank(timestampStr)) {
|
if (StrUtil.isBlank(timestampStr)) {
|
||||||
ResponseWriter.writeSuccess(response, ResultCode.MOBILE_TIMESTAMP_REQUIRED);
|
writeErrorResponse(response, ResultCode.MOBILE_TIMESTAMP_REQUIRED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,28 +89,28 @@ public class MobileApiSignatureFilter extends OncePerRequestFilter {
|
|||||||
try {
|
try {
|
||||||
timestamp = Long.parseLong(timestampStr);
|
timestamp = Long.parseLong(timestampStr);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
ResponseWriter.writeSuccess(response, ResultCode.MOBILE_TIMESTAMP_INVALID);
|
writeErrorResponse(response, ResultCode.MOBILE_TIMESTAMP_INVALID);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 验证时间戳是否在有效期内
|
// 3. 验证时间戳是否在有效期内
|
||||||
long currentTime = System.currentTimeMillis();
|
long currentTime = System.currentTimeMillis();
|
||||||
if (Math.abs(currentTime - timestamp) > SIGN_VALID_DURATION) {
|
if (Math.abs(currentTime - timestamp) > SIGN_VALID_DURATION) {
|
||||||
ResponseWriter.writeSuccess(response, ResultCode.MOBILE_TIMESTAMP_EXPIRED);
|
writeErrorResponse(response, ResultCode.MOBILE_TIMESTAMP_EXPIRED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. 获取签名
|
// 4. 获取签名
|
||||||
String sign = request.getHeader(HEADER_SIGN);
|
String sign = request.getHeader(HEADER_SIGN);
|
||||||
if (StrUtil.isBlank(sign)) {
|
if (StrUtil.isBlank(sign)) {
|
||||||
ResponseWriter.writeSuccess(response, ResultCode.MOBILE_SIGN_REQUIRED);
|
writeErrorResponse(response, ResultCode.MOBILE_SIGN_REQUIRED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. 获取设备密钥(从Redis或数据库)
|
// 5. 获取设备密钥(从Redis或数据库)
|
||||||
// String deviceSecret = getDeviceSecret(deviceId);
|
// String deviceSecret = getDeviceSecret(deviceId);
|
||||||
// if (StrUtil.isBlank(deviceSecret)) {
|
// if (StrUtil.isBlank(deviceSecret)) {
|
||||||
// ResponseWriter.writeSuccess(response, ResultCode.MOBILE_DEVICE_NOT_REGISTERED);
|
// writeErrorResponse(response, ResultCode.MOBILE_DEVICE_NOT_REGISTERED);
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@@ -118,7 +118,7 @@ public class MobileApiSignatureFilter extends OncePerRequestFilter {
|
|||||||
String expectedSign = generateSign(request);
|
String expectedSign = generateSign(request);
|
||||||
logger.info("Expected sign: " + expectedSign);
|
logger.info("Expected sign: " + expectedSign);
|
||||||
if (!sign.equals(expectedSign)) {
|
if (!sign.equals(expectedSign)) {
|
||||||
ResponseWriter.writeSuccess(response, ResultCode.MOBILE_SIGN_INVALID);
|
writeErrorResponse(response, ResultCode.MOBILE_SIGN_INVALID);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,4 +184,12 @@ public class MobileApiSignatureFilter extends OncePerRequestFilter {
|
|||||||
// 3. 生成MD5签名
|
// 3. 生成MD5签名
|
||||||
return DigestUtil.sha256Hex(sb.toString());
|
return DigestUtil.sha256Hex(sb.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void writeErrorResponse(HttpServletResponse response, ResultCode resultCode) throws IOException {
|
||||||
|
response.setStatus(HttpStatus.BAD_REQUEST.value());
|
||||||
|
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||||
|
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
||||||
|
Result<?> result = Result.failed(resultCode);
|
||||||
|
response.getWriter().write(JSONUtil.toJsonStr(result));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user