当前位置:   article > 正文

微服务获取当前登录用户信息

微服务获取当前登录用户信息

一,实现思路


1,基于JWT令牌登陆方式

  • JWT实现登录的,登录信息就保存在请求头的token中。因此要获取当前登录用户,只要获取请求头,解析其中的token。

1),Gateway网关拦截,解析用户信息

  • 我们的把token解析的行为放到了网关中,然后网关把用户信息放入请求头,传递给下游微服务。
    • 在Gateway网关中创建一个Filter,拦截并解析JWT,将用户消息放入请求头中
      1. @Component
      2. public class AccountAuthFilter implements GlobalFilter, Ordered {
      3. private final AuthUtil authUtil;
      4. private final AuthProperties authProperties;
      5. private final AntPathMatcher antPathMatcher = new AntPathMatcher();
      6. public AccountAuthFilter(AuthUtil authUtil, AuthProperties authProperties) {
      7. this.authUtil = authUtil;
      8. this.authProperties = authProperties;
      9. }
      10. @Override
      11. public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
      12. // 1.获取请求request信息
      13. ServerHttpRequest request = exchange.getRequest();
      14. String method = request.getMethodValue();
      15. String path = request.getPath().toString();
      16. String antPath = method + ":" + path;
      17. // 2.判断是否是无需登录的路径
      18. if(isExcludePath(antPath)){
      19. // 直接放行
      20. return chain.filter(exchange);
      21. }
      22. // 3.尝试获取用户信息
      23. List<String> authHeaders = exchange.getRequest().getHeaders().get(AUTHORIZATION_HEADER);
      24. String token = authHeaders == null ? "" : authHeaders.get(0);
      25. R<LoginUserDTO> r = authUtil.parseToken(token);
      26. // 4.如果用户是登录状态,尝试更新请求头,传递用户信息
      27. if(r.success()){
      28. exchange.mutate()
      29. .request(builder -> builder.header(自定义请求头名称, r.getData().getUserId().toString()))
      30. .build();
      31. }
      32. // 6.放行
      33. return chain.filter(exchange);
      34. }
      35. private boolean isExcludePath(String antPath) {
      36. for (String pathPattern : authProperties.getExcludePath()) {
      37. if(antPathMatcher.match(pathPattern, antPath)){
      38. return true;
      39. }
      40. }
      41. return false;
      42. }
      43. @Override
      44. public int getOrder() {
      45. return 1000;
      46. }
      47. }

2),微服务获取用户信息,并将用户信息放入ThreadLocal中

每个微服务都定义一个Filter,获取用户信息。并使用ThreadLocal 将用户信息放入ThreadLocal中,每个微服务都定义很麻烦,所以我们将Filter抽取出来。

  1. @Slf4j
  2. public class UserInfoInterceptor implements HandlerInterceptor {
  3. @Override
  4. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  5. // 1.尝试获取头信息中的用户信息
  6. String authorization = request.getHeader(请求头名称);
  7. // 2.判断是否为空 因为很多微服务不需要获取用户信息我们不需要拦截
  8. if (authorization == null) {
  9. return true;
  10. }
  11. // 3.转为用户id并保存
  12. try {
  13. Long userId = Long.valueOf(authorization);
  14. UserContext.setUser(userId);
  15. return true;
  16. } catch (NumberFormatException e) {
  17. log.error("用户身份信息格式不正确,{}, 原因:{}", authorization, e.getMessage());
  18. return true;
  19. }
  20. }
  21. @Override
  22. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
  23. // 清理用户信息
  24. UserContext.removeUser();
  25. }
  26. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/194447
推荐阅读
相关标签
  

闽ICP备14008679号