如何优雅地将Token参数转换成userId

在实际项目中,我们往往会发放一个token凭证给前端,前端在每次请求的时候通过请求参数或者请求头将token传给后端进行验证。后端在获得token,验证通过之后会将token转成实际需要的参数,比如userId

SrpingBoot项目中,由于在请求参数中并没有userId这个参数,所以我们无法通过方法形参获取到userId,因此我们需要通过HttpServletWrapper来将token转换成userId参数。

1、继承HttpServletWrapper类,并重写getParameterValues方法

注:此处并没有使用真正的token,而是用一个map模拟token存储,
token123456为有效token,分别对应着userId = 1userId = 2

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
30
31
32
33
34
35
36
37
38
复制代码/**
* Token请求包装类,将token字段转换成userId字段
* @author yan
* @date 2019年10月17日
*/
public class TokenHttpServletWrapper extends HttpServletRequestWrapper{
private Logger logger = LoggerFactory.getLogger(getClass());

private Map<String,Integer> tokenMap; //模拟token

public TokenHttpServletWrapper(HttpServletRequest request) {
super(request);
tokenMap = new HashMap<>() {
{
put("123", 1);
put("456", 2);
}
};
}


@Override
public String[] getParameterValues(String name) {
//如果请求参数不是userId,则跳过
if(!"userId".equals(name)) {
return super.getParameterValues(name);
}
//检验token,转换成相应的userId
String token = super.getParameter("token");
if(token == null) {
return null;
}
logger.debug("token:" + token);
Integer userId = tokenMap.get(token);
logger.debug("userId:" + userId);
return userId == null ? null : new String[] {String.valueOf(userId)};
}
}

2、定义过滤器,判断是否有token参数或者token参数是否有效

AbstractFilter是自定义过滤器抽象类,主要用于添加排除路径功能,其他用法与过滤器一致

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
复制代码public class TokenFilter extends AbstractFilter{

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
String token = request.getParameter("token");
if(!"123".equals(token) && !"456".equals(token)) {
CodeResult codeResult = new CodeResult(CodeEnum.UNAUTHORIZED, null);
response.setContentType("text/json;charset=utf-8");
response.getWriter().write(BeanUtil.beanToJson(codeResult));
return;
}
chain.doFilter(new TokenHttpServletWrapper(request), response);
}

}

3、配置过滤器

1
2
3
4
5
6
7
8
9
10
11
12
13
复制代码@Configuration
public class TokenFilterConfig {
@Bean
public FilterRegistrationBean<Filter> securityFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
Filter filter = new TokenFilter();
registration.setFilter(filter);
registration.addUrlPatterns("/*");
registration.setName("tokenFilter");
registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
return registration;
}
}

4、在Controller方法中使用userId作为形参

5、请求访问该接口

  1. 当没有token参数时或者token参数无效时,返回未授权信息

  1. token参数有效时,获取到相应的userId

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%