From 7a2b991aa05c7f5eb8c041a805021e2d1a8f3a3f Mon Sep 17 00:00:00 2001 From: zjf <1799650030@qq.com> Date: Tue, 1 Sep 2026 20:52:22 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=9F=AD=E4=BF=A1=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../handle/GlobalBizExceptionHandler.java | 12 ++-- .../controller/ThirdPartyOAth2Cotroller.java | 67 ++++++++++--------- 2 files changed, 42 insertions(+), 37 deletions(-) diff --git a/pjcloud-common/pjcloud-common-sentinel/src/main/java/com/bsd/pjcloud/common/sentinel/handle/GlobalBizExceptionHandler.java b/pjcloud-common/pjcloud-common-sentinel/src/main/java/com/bsd/pjcloud/common/sentinel/handle/GlobalBizExceptionHandler.java index 0d172c1df..7e5036f6d 100644 --- a/pjcloud-common/pjcloud-common-sentinel/src/main/java/com/bsd/pjcloud/common/sentinel/handle/GlobalBizExceptionHandler.java +++ b/pjcloud-common/pjcloud-common-sentinel/src/main/java/com/bsd/pjcloud/common/sentinel/handle/GlobalBizExceptionHandler.java @@ -21,7 +21,6 @@ import com.alibaba.csp.sentinel.Tracer; import com.fasterxml.jackson.databind.ObjectMapper; import com.bsd.pjcloud.common.core.util.R; import feign.FeignException; -import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.security.access.AccessDeniedException; @@ -73,7 +72,6 @@ public class GlobalBizExceptionHandler { return R.failed("数据库调用异常,请联系管理员处理"); } - @SneakyThrows @ExceptionHandler(FeignException.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) public R handleGlobalException(FeignException e) { @@ -83,10 +81,16 @@ public class GlobalBizExceptionHandler { Tracer.trace(e); if (e.responseBody().isPresent()) { - return objectMapper.readValue(e.responseBody().get().array(), R.class); + try { + return objectMapper.readValue(e.responseBody().get().array(), R.class); + } catch (Exception parseEx) { + // 下游返回非 JSON(或 JDK 序列化魔数 0xAC 等)时,勿把 Jackson 原文抛给前端 + log.warn("Feign 错误响应非 JSON,status={}", e.status()); + return R.failed("下游服务异常,请稍后重试"); + } } - return R.failed(e.getLocalizedMessage()); + return R.failed("服务调用失败,请稍后重试"); } /** diff --git a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/ThirdPartyOAth2Cotroller.java b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/ThirdPartyOAth2Cotroller.java index 59ebe2c50..359d755c8 100644 --- a/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/ThirdPartyOAth2Cotroller.java +++ b/pjcloud-thirdparty/pjcloud-thirdparty-biz/src/main/java/com/bsd/pjcloud/thirdparty/controller/ThirdPartyOAth2Cotroller.java @@ -242,13 +242,13 @@ public class ThirdPartyOAth2Cotroller { } reqParam = reqParam + ",employeeCode=" + snap.getEmployeeCode(); String redisKey = CacheConstants.SMS_CODE_KEY + dto.getMobilePhone(); - String storedCode = (String) redisTemplate.opsForValue().get(redisKey); + String storedCode = stringRedisTemplate.opsForValue().get(redisKey); if (!dto.getSmsCode().equals(storedCode)) { R failed = R.failed("验证码错误"); recordZzdSsoControllerLog("/thirdPartyOAth2/zzdsso/confirmPhone", reqParam, failed, startMs, "confirmPhone"); return failed; } - redisTemplate.delete(redisKey); + stringRedisTemplate.delete(redisKey); R> byPhone = remoteUserService.getUserByMobile(dto.getMobilePhone()); List users = byPhone.getData(); @@ -407,33 +407,37 @@ public class ThirdPartyOAth2Cotroller { @SysLog("设备验证") @Inner(value = false) public R verifyDevice(@RequestBody DeviceVerifyDTO dto, HttpServletRequest httpServletRequest) { - // 1. 校验验证码 - String redisKey = "smsCode_" + dto.getMobilePhone(); - String storedCode = (String) redisTemplate.opsForValue().get(redisKey); - if (!dto.getCode().equals(storedCode)) { - return R.failed("验证码错误"); + if (dto == null || !StringUtils.isNoneBlank(dto.getMobilePhone(), dto.getCode())) { + return R.failed("手机号或验证码不能为空"); } - - // 验证成功后移除验证码(可选) - redisTemplate.delete(redisKey); - + // 1. 校验验证码(必须用 StringRedisTemplate,与 loginSms 写入一致;Jackson Redis 读到 JDK 序列化值会报 ¬/0xAC) + String redisKey = CacheConstants.SMS_CODE_KEY + dto.getMobilePhone().trim(); + String storedCode = stringRedisTemplate.opsForValue().get(redisKey); + if (storedCode == null || !dto.getCode().trim().equals(storedCode)) { + return R.failed("验证码错误或已过期"); + } + stringRedisTemplate.delete(redisKey); // 2. 记录信任设备 - //查询之前的是否有过期的数据,有就更新 - String generate = DeviceFingerprintUtil.generate(httpServletRequest); - R userTrustedDeviceR = remoteUserTrustedDeviceService.getUserTrustedDeviceByIdAndMD5(dto.getMobilePhone(), generate, SH_DEVICE_NAME); - if (userTrustedDeviceR.getData() != null) { - userTrustedDeviceR.getData().setExpireTime(LocalDateTime.now().plusMonths(6)); - remoteUserTrustedDeviceService.updateById(userTrustedDeviceR.getData()); - } else { - UserTrustedDeviceEntity userTrustedDevice = new UserTrustedDeviceEntity(); - userTrustedDevice.setMobilePhone(dto.getMobilePhone()); - userTrustedDevice.setExpireTime(LocalDateTime.now().plusMonths(6)); - userTrustedDevice.setDeviceName(SH_DEVICE_NAME); - userTrustedDevice.setDeviceFingerprint(generate); - remoteUserTrustedDeviceService.save(userTrustedDevice); + try { + String generate = DeviceFingerprintUtil.generate(httpServletRequest); + R userTrustedDeviceR = remoteUserTrustedDeviceService.getUserTrustedDeviceByIdAndMD5(dto.getMobilePhone().trim(), generate, SH_DEVICE_NAME); + if (userTrustedDeviceR != null && userTrustedDeviceR.getData() != null) { + userTrustedDeviceR.getData().setExpireTime(LocalDateTime.now().plusMonths(6)); + remoteUserTrustedDeviceService.updateById(userTrustedDeviceR.getData()); + } else { + UserTrustedDeviceEntity userTrustedDevice = new UserTrustedDeviceEntity(); + userTrustedDevice.setMobilePhone(dto.getMobilePhone().trim()); + userTrustedDevice.setExpireTime(LocalDateTime.now().plusMonths(6)); + userTrustedDevice.setDeviceName(SH_DEVICE_NAME); + userTrustedDevice.setDeviceFingerprint(generate); + remoteUserTrustedDeviceService.save(userTrustedDevice); + } + return R.ok(); + } catch (Exception e) { + log.error("[verify-device] 保存信任设备失败 mobile={}", dto.getMobilePhone(), e); + return R.failed("设备验证失败,请稍后重试"); } - return R.ok(); } @PostMapping("/mini-app/verify-device") @@ -442,13 +446,12 @@ public class ThirdPartyOAth2Cotroller { public R miniVerifyDevice(@RequestBody DeviceVerifyDTO dto, HttpServletRequest httpServletRequest) { // 1. 校验验证码 - String redisKey = "smsCode_" + dto.getMobilePhone(); - String storedCode = (String) redisTemplate.opsForValue().get(redisKey); + String redisKey = CacheConstants.SMS_CODE_KEY + dto.getMobilePhone(); + String storedCode = stringRedisTemplate.opsForValue().get(redisKey); if (!dto.getCode().equals(storedCode)) { return R.failed("验证码错误"); } - // 验证成功后移除验证码(可选) - redisTemplate.delete(redisKey); + stringRedisTemplate.delete(redisKey); // 2. 记录信任设备 //查询之前的是否有过期的数据,有就更新 @@ -516,14 +519,12 @@ public class ThirdPartyOAth2Cotroller { stringHashMap.put("date", "5"); smsService.sendSms(mobilePhone, "20657", stringHashMap, WebUtils.getIP()); - // null 适配之前诗画的,=1访客,先else + // null 适配之前诗画的,=1访客;验证码一律 String 存储,避免 Jackson Redis 与 JDK 序列化混用 if (null == type) { - redisTemplate.opsForValue().set(CacheConstants.SMS_CODE_KEY + mobilePhone, s, 5, TimeUnit.MINUTES); + stringRedisTemplate.opsForValue().set(CacheConstants.SMS_CODE_KEY + mobilePhone, s, 5, TimeUnit.MINUTES); } else { stringRedisTemplate.opsForValue().set(CacheConstants.SMS_VISITOR_CODE_KEY + mobilePhone, s, 5, TimeUnit.MINUTES); - } -// redisTemplate.opsForValue().set(CacheConstants.SMS_CODE_KEY +mobilePhone,s, 5, TimeUnit.MINUTES); return R.ok(); }