[RuoYi 프로젝트 분석] 게이트웨이의 AuthFilter는 "인증"을 완료합니다. 권한이 아닌 인증이라는 점에 유의하세요.


필터의 기능은 게이트웨이를 통과하는 모든 요청을 확인하고 토큰의 정보가 유효한지 확인하는 것입니다.
'권한'이 아닌 '인증 확인'임을 참고하세요.

1. 기능 소개

1. 사용자가 로그인을 완료한 후 프로그램은 사용자 관련 사용자, 역할, 권한 및 기타 정보를 Redis에 임시 저장하고 최종 사용자에게 토큰을 반환합니다.

1. 결국 반환된 토큰은 너무 많은 데이터 전송을 피하기 위해 아주 적은 양의 사용자 정보만 저장합니다
2. RuoYi가 반환한 토큰에 저장되는 정보는 다음과 같습니다:
user_key: login_tokens:uuid (redis에 저장하는 데 사용됨)
user_id : userId
사용자 이름: userName

2. 사용자가 토큰을 소지하면 토큰이 유효한지, 관련 사용자가 로그인했는지 여부를 확인합니다. 토큰이 유효한 경우 user_key, user_id 및 사용자 이름을 요청 헤더에 설정합니다.

여기서 주요 목적은 토큰이 유효한지 확인하는 것입니다.
요청 헤더에 설정하여 균일하게 처리하므로 다른 모듈에도 편리합니다.

2. AuthFilter 구성

@Component
public class AuthFilter implements GlobalFilter, Ordered
{
    
    
    private static final Logger log = LoggerFactory.getLogger(AuthFilter.class);
    
    @Autowired
    private RedisService redisService;


    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
    {
    
    
        ...
    }
}

AuthFilter는 GlobalFilter, Ordered를 구현하며 모든 모듈에 있는 전역 필터입니다. 이 역시 이해하기 쉽습니다.물론 모든 모듈에서는 토큰이 유효한지 확인해야 합니다.

3. AuthFilter 구현 분석

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
    {
    
    
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpRequest.Builder mutate = request.mutate();

        String url = request.getURI().getPath();
        // 1、检验路径
        if (StringUtils.matches(url, ignoreWhite.getWhites()))
        {
    
    
            return chain.filter(exchange);
        }
        String token = getToken(request);
        // 2、是否有token
        if (StringUtils.isEmpty(token))
        {
    
    
            return unauthorizedResponse(exchange, "令牌不能为空");
        }
        // 3、解析token,判断是否是有效的token
        Claims claims = JwtUtils.parseToken(token);
        if (claims == null)
        {
    
    
            return unauthorizedResponse(exchange, "令牌已过期或验证不正确!");
        }
        String userkey = JwtUtils.getUserKey(claims);
        // 4、判断用户是否登录
        boolean islogin = redisService.hasKey(getTokenKey(userkey));
        if (!islogin)
        {
    
    
            return unauthorizedResponse(exchange, "登录状态已过期");
        }
        String userid = JwtUtils.getUserId(claims);
        String username = JwtUtils.getUserName(claims);
        // 5、检查token是否有userId、userName
        if (StringUtils.isEmpty(userid) || StringUtils.isEmpty(username))
        {
    
    
            return unauthorizedResponse(exchange, "令牌验证失败");
        }

        // 6、设置用户信息到请求
        addHeader(mutate, SecurityConstants.USER_KEY, userkey);
        addHeader(mutate, SecurityConstants.DETAILS_USER_ID, userid);
        addHeader(mutate, SecurityConstants.DETAILS_USERNAME, username);
        // 7、内部请求来源参数清除
        removeHeader(mutate, SecurityConstants.FROM_SOURCE);
        return chain.filter(exchange.mutate().request(mutate.build()).build());
    }

1. 경로를 확인합니다.
경로 uri가 화이트리스트에 있으며, 화이트리스트에 있으면 바로 통과됩니다.
2. 토큰 존재 여부
3. 토큰을 구문 분석하여 유효한 토큰인지 확인합니다.
유효한 토큰만이 오류 보고 없이 정보를 구문 분석합니다.
4.
사용자의 로그인 여부를 확인하는 auth의 권한 확인에는 사용자의 로그인 여부를 확인하는 주석이 있습니다.
5. 토큰에 userId 및 userName이 있는지 확인하십시오.
6. 요청 헤더에 사용자 정보를 설정하십시오.
7. 내부 요청 소스 매개변수를 지우십시오
. 8. 다음 필터로 계속하십시오.

4. 정보 참고

Yuque 노트 주소: https://www.yuque.com/yuchangyuan/tkb5br

추천

출처blog.csdn.net/yuchangyuan5237/article/details/133473706