JWT认证应用中,能否在过滤器通过Token获取用户并传入控制器方法参数?
当然完全可行!这在Spring开发里是非常常见的实践,我给你一步步讲清楚怎么实现,保证你能快速落地:
实现步骤拆解
1. 过滤器中解析JWT并存储用户信息
首先,在你的JWT过滤器里完成Token解析,拿到用户信息后,把它存到当前请求的属性里——就像给请求“贴个标签”,后面的控制器就能直接取到这个标签里的内容。示例代码大概是这样:
public class JwtAuthenticationFilter extends OncePerRequestFilter { private JwtTokenProvider jwtTokenProvider; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // 从请求头里提取JWT Token String token = extractTokenFromRequest(request); if (token != null && jwtTokenProvider.validateToken(token)) { // 解析Token得到用户对象 User user = jwtTokenProvider.getUserFromToken(token); // 将用户对象存入请求属性,方便后续获取 request.setAttribute("currentUser", user); } // 继续执行过滤器链 filterChain.doFilter(request, response); } private String extractTokenFromRequest(HttpServletRequest request) { String bearerToken = request.getHeader("Authorization"); if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) { return bearerToken.substring(7); } return null; } }
2. 自定义参数解析器
接下来要实现Spring的HandlerMethodArgumentResolver接口——这个接口的作用就是把请求里的内容转换成控制器方法能直接用的参数。我们可以专门写一个解析器,从请求属性里取出刚才存的用户对象。
为了更灵活,先定义一个自定义注解,用来标记控制器里需要注入当前用户的参数:
@Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface CurrentUser { }
然后实现参数解析器:
public class CurrentUserArgumentResolver implements HandlerMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter parameter) { // 判断参数是否带有@CurrentUser注解,并且类型是我们的User对象 return parameter.hasParameterAnnotation(CurrentUser.class) && parameter.getParameterType().equals(User.class); } @Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { // 从请求属性里取出用户对象返回 HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class); return request.getAttribute("currentUser"); } }
3. 把参数解析器注册到Spring容器
最后要告诉Spring这个自定义解析器的存在,在MVC配置类里把它加进去:
@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) { resolvers.add(new CurrentUserArgumentResolver()); } }
4. 在控制器里直接使用
现在你就可以在控制器方法里轻松拿到用户对象了,不用再手动处理Token解析:
@RestController @RequestMapping("/api") public class UserController { @GetMapping("/profile") public ResponseEntity<User> getProfile(@CurrentUser User currentUser) { // 直接使用currentUser对象做业务逻辑 return ResponseEntity.ok(currentUser); } }
额外注意事项
- 要确保你的JWT过滤器执行顺序在Spring其他相关过滤器之前,保证用户信息在控制器处理请求前就已经存入请求属性。
- 如果Token解析失败(比如过期、无效),可以在过滤器里直接返回401等错误响应,不用继续往下执行。
- 你也可以选择把用户对象存入
SecurityContextHolder,不过用请求属性的方式更轻量,适配这种参数注入的场景刚好。
内容的提问来源于stack exchange,提问作者JVic
相关产品推荐
相关产品推荐

