本文介绍: 身份验证令牌(Authentication Token):在身份验证过程中,“token可以表示一个包用户身份信息的令牌。例如Token(JWT)是一种常见的身份验证令牌,它包含用户的身份信息(例如用户名用户ID)以及其他相关信息,如权限过期时间。无意义令牌token,这种一般在获取通过nosql查询token对应用户信息。当然,设计token网上大多有现成的解决方案,但是通过token如何个人信息呢?我还是推荐方法1,无疑,虽然多查一次,但是结构简单,耦合度低,并且代码较为简洁

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. 创建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. 过滤器二次封装请求

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

@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);	
}

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

3. 总结

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

原文地址:https://blog.csdn.net/faker1234546/article/details/132984895

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_19779.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注