| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- package com.poyee.aspect;
- import cn.hutool.core.util.StrUtil;import com.alibaba.fastjson.JSON;
- import com.alibaba.fastjson.JSONObject;
- import com.poyee.annotation.NoLogin;
- import com.poyee.annotation.UserLoginToken;
- import com.poyee.exception.BusinessException;
- import com.poyee.utils.JwtUtils;
- import com.poyee.utils.ServletUtils;
- import lombok.extern.slf4j.Slf4j;
- import org.aspectj.lang.JoinPoint;
- import org.aspectj.lang.Signature;
- import org.aspectj.lang.annotation.Aspect;
- import org.aspectj.lang.annotation.Before;
- import org.aspectj.lang.annotation.Pointcut;
- import org.aspectj.lang.reflect.MethodSignature;
- import org.springframework.stereotype.Component;
- import javax.servlet.http.HttpServletRequest;
- import java.lang.reflect.Method;
- import java.nio.charset.StandardCharsets;
- import java.util.Arrays;
- import java.util.Base64;
- /**
- * 用户登录Token切面
- */
- @Slf4j
- @Aspect
- @Component
- public class UserLoginTokenAspect {
- /**
- * 配置织入点 - 拦截所有 Controller 方法
- */
- @Pointcut("execution(public * com.poyee.controller.*.*(..))")
- public void controllerPointCut() {
- }
- /**
- * 前置通知
- */
- @Before("controllerPointCut()")
- public void doBefore(JoinPoint joinPoint) {
- HttpServletRequest request = ServletUtils.getRequest();
- if (request == null) {
- return;
- }
- // 获取方法上的注解
- Signature signature = joinPoint.getSignature();
- MethodSignature methodSignature = (MethodSignature) signature;
- Method method = methodSignature.getMethod();
- Class<?> declaringClass = method.getDeclaringClass();
- // 1. 检查是否有 @NoLogin 注解(方法级别优先)
- NoLogin noLogin = method.getAnnotation(NoLogin.class);
- if (noLogin == null) {
- noLogin = declaringClass.getAnnotation(NoLogin.class);
- }
- // 如果有 @NoLogin 注解,直接放行
- if (noLogin != null) {
- return;
- }
- // 2. 没有 @NoLogin 注解,一律进行 Token 检查
- String userInfoStr = request.getHeader("X-USER-BASE64");
- if (StrUtil.isBlank(userInfoStr)) {
- userInfoStr = request.getHeader("x-user-base64");
- }
- log.info("X-USER-BASE64 >>> {}", userInfoStr);
- String authorization = request.getHeader("Authorization");
- log.info("Authorization >>> {}", authorization);
- // 3. 检查是否有 @UserLoginToken 注解(用于角色控制)
- UserLoginToken userLoginToken = method.getAnnotation(UserLoginToken.class);
- if (userLoginToken == null) {
- userLoginToken = declaringClass.getAnnotation(UserLoginToken.class);
- }
- // 执行登录检查
- checkUserLoginToken(request, userInfoStr, authorization, userLoginToken);
- }
- /**
- * 检查用户登录Token
- */
- private void checkUserLoginToken(HttpServletRequest request, String userInfoStr,
- String authorization, UserLoginToken userLoginToken) {
- boolean isAuthorization = false;
- String token = userInfoStr;
- // 1. 尝试从 X-USER-BASE64 获取
- if (StrUtil.isBlank(token)) {
- // 2. 尝试从 Authorization 获取
- if (StrUtil.isNotBlank(authorization)) {
- if (authorization.startsWith("Bearer ")) {
- isAuthorization = true;
- token = authorization.substring(7);
- } else {
- token = authorization;
- }
- }
- }
- if (StrUtil.isBlank(token)) {
- throw new BusinessException(401, "未登录或登录已过期");
- }
- // 保存原始token到session
- ServletUtils.getSession().setAttribute("x-user-base64", token);
- // 解析用户信息
- JSONObject userInfo = parseUserInfo(token, isAuthorization);
- if (userInfo == null) {
- throw new BusinessException(402, "登录信息无效,请重新登录");
- }
- // 保存用户信息到request
- request.setAttribute("currentUser", userInfo);
- ServletUtils.getSession().setAttribute("userInfo", JSON.toJSONString(userInfo));
- // 检查角色权限(如果有 @UserLoginToken 注解且配置了角色)
- if (userLoginToken != null && userLoginToken.roles().length > 0) {
- boolean hasRole = checkRole(userInfo, userLoginToken.roles());
- if (!hasRole) {
- throw new BusinessException(403, "无权访问");
- }
- }
- log.info("用户登录验证通过: {}", userInfo.getString("username"));
- }
- /**
- * 解析用户信息
- */
- private JSONObject parseUserInfo(String token, boolean isAuthorization) {
- try {
- if (isAuthorization) {
- // JWT Token 解析
- return JwtUtils.getTokenUserInfo(token);
- } else {
- // Base64 编码的用户信息
- String jsonStr = new String(Base64.getDecoder().decode(token), StandardCharsets.UTF_8);
- return JSON.parseObject(jsonStr);
- }
- } catch (Exception e) {
- log.error("解析用户信息失败", e);
- return null;
- }
- }
- /**
- * 检查用户角色
- */
- private boolean checkRole(JSONObject userInfo, String[] requiredRoles) {
- if (userInfo == null) {
- return false;
- }
- String role = userInfo.getString("role");
- if (role == null) {
- return false;
- }
- return Arrays.asList(requiredRoles).contains(role);
- }
- }
|