一、自定义登录拦截器,拦截请求,获取header中 的token信息校验拦截

@Component
public class LoginFilter implements GlobalFilter, Ordered {

    private static final String AUTHORIZE_TOKEN = "accessToken";

    private static AntPathMatcher matcher = new AntPathMatcher();

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

        ServerHttpRequest request = exchange.getRequest();
        // 不需要拦截的url直接放行
        if(needLogin(request.getPath().toString())){
            return chain.filter(exchange);
        }

        String accessToken = request.getHeaders().getFirst(AUTHORIZE_TOKEN);
        if (StringUtils.isBlank(accessToken)) {
            return loginResponse(exchange);
        }

        try {
            Claims claims = JwtUtil.checkJWT(accessToken);
            LoginUser loginUser = new LoginUser();
            loginUser.setUserId((String) claims.get("userId"));
            loginUser.setMobile((String) claims.get("mobile"));

            // 将accessToken中的信息传入到请求头中,方便后续接口使用
            request.mutate().header("LOGIN_USER", JSONObject.toJSONString(loginUser)).build();
        } catch (Exception e) {
            return loginResponse(exchange);
        }

        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }

    public static Mono<Void> loginResponse(ServerWebExchange exchange) {
        JSONObject resultJson = new JSONObject();
        resultJson.put("code", 401);
        resultJson.put("message", "请重新登陆授权");
        resultJson.put("status", 401);
        ServerHttpResponse response = exchange.getResponse();
        byte[] bytes = JSONObject.toJSONBytes(resultJson);
        response.getHeaders().add("Content-Type", MediaType.APPLICATION_JSON_VALUE);
        DataBuffer buffer = response.bufferFactory().wrap(bytes);
        return response.writeWith(Flux.just(buffer));
    }

    public static boolean needLogin(String uri){
        // test
        List<String> uriList = new ArrayList<>();
        uriList.add("/user/login");
        uriList.add("/order/list");

        for (String pattern : uriList) {
            if (matcher.match(pattern, uri)) {
                // 不需要拦截
                return true;
            }
        }
        return false;
    }
}

二、HandlerMethodArgumentResolver参数解析器获取登录用户信息
gateway拦截器中已经将用户信息校验并传入到请求头中,再通过参数解析器在接口中直接获取使用当前登录用户的信息
1.实现HandlerMethodArgumentResolver接口

public class LoginUserMethodArgumentResolver implements HandlerMethodArgumentResolver {

	//判断参数中是否有LoginUser,有就执行下面resolveArgument的方法
    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        return methodParameter.getParameterType().isAssignableFrom(LoginUser.class);
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
		//从请求头中获取用户信息
        String loginUserStr = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getHeader("LOGIN_USER");
        LoginUser loginUser = JSONObject.parseObject(loginUserStr, LoginUser.class);
        return loginUser ;
}

2.配置MVC

@Configuration
public class WebConfigurer implements WebMvcConfigurer {

    @Autowired
    LoginUserMethodArgumentResolver loginUserMethodArgumentResolver;

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(loginUserMethodArgumentResolver);
        WebMvcConfigurer.super.addArgumentResolvers(argumentResolvers);
    }

    @Bean
    public LoginUserMethodArgumentResolver getLoginUserMethodArgumentResolver() {
        return new LoginUserMethodArgumentResolver();
    }
}

3.测试获取用户信息

@RestController
@RequestMapping("/user")
public class UserController {

    @GetMapping("/test")
    public String getLoginUser(LoginUser loginUser) {
        String loginUserStr = JSONObject.toJSONString(loginUser);
        System.out.println(loginUserStr);
        return "success";
    }
}
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐