| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- package com.ruoyi.system.utils;
- import com.ruoyi.common.core.domain.AjaxResult;
- import com.ruoyi.common.core.redis.RedisCache;
- import com.ruoyi.common.exception.ServiceException;
- import com.ruoyi.common.utils.MessageUtils;
- import com.ruoyi.system.domain.InfoUser;
- import com.ruoyi.system.mapper.InfoUserMapper;
- import org.aspectj.lang.ProceedingJoinPoint;
- import org.aspectj.lang.annotation.Around;
- import org.aspectj.lang.annotation.Aspect;
- import org.aspectj.lang.annotation.Pointcut;
- import org.aspectj.lang.reflect.MethodSignature;
- import org.springframework.stereotype.Component;
- import jakarta.annotation.Resource;
- import jakarta.servlet.http.HttpServletRequest;
- import java.util.Map;
- /**
- * Created with IntelliJ IDEA.
- *
- * @Auther: ZouTiancong
- * @Date: 2022/05/23/22:39
- * @Description:
- */
- @Component
- @Aspect
- public class AuthAspect {
- private HttpServletRequest request;
- private final RedisCache redisCache;
- private final InfoUserMapper infoUserMapper;
- public AuthAspect(RedisCache redisCache, InfoUserMapper infoUserMapper) {
- this.redisCache = redisCache;
- this.infoUserMapper = infoUserMapper;
- }
- @Resource
- public void setHttpServletRequest(HttpServletRequest request) {
- this.request = request;
- }
- @Pointcut("@annotation(com.ruoyi.system.utils.Auth)")
- private void authPointcut() {
- }
- @Around("authPointcut()")
- public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
- // 获取方法签名信息从而获取方法名和参数类型
- MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
- // 获取目标方法对象上注解中的属性值
- Auth auth = methodSignature.getMethod().getAnnotation(Auth.class);
- // JWT 只解析和验签一次,后续会话校验及 Controller 均复用这里提取的可信身份。
- if (auth.token()) {
- Map<String, Object> claims = JwtUtil.verifyToken(request.getHeader("token"));
- if (!Boolean.TRUE.equals(claims.get("valid"))) {
- return AjaxResult.error(401,"token已过期,请重新登录!");
- }
- Long userId = parseUserId(claims.get("id"));
- Object jtiValue = claims.get("jti");
- String jti = jtiValue instanceof String ? (String) jtiValue : null;
- if (auth.session() && (userId == null || jti == null || jti.isBlank()
- || !Boolean.TRUE.equals(redisCache.hasKey(jti)))) {
- // Redis 会话校验只服务商家侧账号的即时撤销;普通用户和骑手没有会话撤销用途,
- // 旧 token(jti 从未写入 Redis)放行,凭已验签的 JWT 通过即可。
- if (!isConsumerUser(userId)) {
- throw new ServiceException(MessageUtils.message("merchant.session.invalid"));
- }
- }
- request.setAttribute(AuthContext.USER_ID_ATTRIBUTE, userId);
- request.setAttribute(AuthContext.JTI_ATTRIBUTE, jti);
- }
- return joinPoint.proceed();
- }
- /**
- * 会话缺失时判断是否为无需商家会话的账号类型:0=普通用户、2=骑手。
- * 商家侧类型(1/3/4/5)、用户不存在或类型未知时一律不放行。
- */
- private boolean isConsumerUser(Long userId) {
- if (userId == null) {
- return false;
- }
- InfoUser user = infoUserMapper.selectById(userId);
- String userType = user == null ? null : user.getUserType();
- return "0".equals(userType) || "2".equals(userType);
- }
- private Long parseUserId(Object claim) {
- if (!(claim instanceof String value) || value.isBlank() || "null".equals(value)) {
- return null;
- }
- try {
- return Long.valueOf(value);
- } catch (NumberFormatException exception) {
- return null;
- }
- }
- }
|