• 如何完美通过token获取用户信息(springboot)


    1. 什么是Token?

    在这里插入图片描述

    身份验证令牌(Authentication Token):在身份验证过程中,“token”
    可以表示一个包含用户身份信息的令牌。

    例如

    1. Token(JWT)是一种常见的身份验证令牌,它包含用户的身份信息(例如用户名或用户ID)以及其他相关信息,如权限或过期时间。
    2. 无意义令牌token,这种一般在获取后通过nosql查询token对应的用户信息。

    当然,设计token网上大多有现成的解决方案,但是通过token如何拿个人信息呢?

    2. 如何优雅的获取用户信息

    虽然token是用户凭证,但是在后端中,token是不能直接和数据进行交互的,我们需要转换成token用户信息。

    解决思路:

    我们大多会在过滤器filter进行token检验,在这里我们已经已经从header中解析并且验证了token了。如果我们要是再在Controller中获取header,在解决,感觉一点也不优雅。
    在这里插入图片描述
    我们的两种解决方案:

    1. 通过header进行解析(推荐):

    哈哈哈,没想到我们还是从这种low的方法里弄的吧。 实际上nosql性能很不错,再查一次也无伤大雅,并且这种方式耦合度较低,符合代码规范。

    我们可以通过注解的方式,可以尽量美观很多
    1.1. 创建CurrentUserUuid接口

    @Target(ElementType.PARAMETER)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface CurrentUserUuid {
    }
    
    • 1
    • 2
    • 3
    • 4

    1.2. 创建oginUserHandlerMethodArgumentResolver解析器
    在这里插入图片描述

    @Component
    public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
        @Resource
        private TokenUtil tokenUtil;
    
        @Override
        public boolean supportsParameter(MethodParameter parameter) {
            return parameter.hasParameterAnnotation(CurrentUserUuid.class) &&
                    parameter.getParameterType().isAssignableFrom(String.class);
        }
    
        @Override
        public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container,
                                      NativeWebRequest request, WebDataBinderFactory factory) {
            // header中获取用户token
            String token = request.getHeader("Authorization");
            // TODO 根据userId获取User信息,这里省略,直接创建一个User对象。
            return tokenUtil.getUserToken(token);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    1. 过滤器二次封装请求体

    我们可以在第一次过滤器查的时候,把对应的信息封装到请求中,但是请求多变,get,post参数一般在不同的位置上,需要写更复杂的结构

    @Override	
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)	
                throws IOException, ServletException {	
        HttpServletRequest httpRequest = (HttpServletRequest) request;	
        HttpServletResponse httpResponse = (HttpServletResponse) response;	
        String token = request.getHeader("token");	
        JWTResult result = JWTUtils.checkToken(token);	
        Long userId = result.getUserId();	
        HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper(httpRequest) {	
                @Override	
                public String[] getParameterValues(String name) {	
                    if (name.equals("loginUserId")) {	
                        return new String[] { userId .toString() };	
                    }	
                    return super.getParameterValues(name);	
                }	
                @Override	
                public Enumeration<String> getParameterNames() {	
                    Set<String> paramNames = new LinkedHashSet<>();	
                    paramNames.add("loginUserId");	
                    Enumeration<String> names =  super.getParameterNames();	
                    while(names.hasMoreElements()) {	
                        paramNames.add(names.nextElement());	
                    }	
                    return Collections.enumeration(paramNames);	
                }	
        };	
        chain.doFilter(requestWrapper, httpResponse);	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    这种好处是只需要查一次,但是请求参数多变,需要写很多额外的解构去处理,并且增加了耦合度

    3. 总结

    我还是推荐方法1,无疑,虽然多查一次,但是结构简单,耦合度低,并且代码较为简洁。

  • 相关阅读:
    有关flask和装饰器的python学习
    硬件混音 饱和失真问题 网页资料
    【进程间通信】进程间通信方式汇总
    Java——聊聊JUC中的锁(synchronized & Lock & ReentrantLock)
    解决requests库中的期限处理问题:从404到异常再到修复
    easyExcel 按照模板设置到处excel内容
    石子合并终极版 (GarsiaWachs算法) [o(n*n)] 板子
    vue2项目搭建结构
    【数据结构】顺序表的增删查改 (C语言实现)
    HTML网页设计【足球科普】学生DW静态网页设计
  • 原文地址:https://blog.csdn.net/faker1234546/article/details/132984895