Spring拦截器解析token设置用户id

1、拦截器代码

@Slf4j
@Component
public class AuthHeaderSettingFilter implements Filter {

    //获取token的userId
    public String getUserIdByToken(HttpServletRequest request) {
        // 获取当前的用户
        String accessToken = request.getHeader("accessToken");
        if (StringUtils.isNotBlank(accessToken)) {
            //解析token获取userId,具体根据项目而定
            String userId = JwtHelpUtil.getUserId(accessToken);
            if (StringUtils.isBlank(userId)) {
                return "";
            }
            return userId;
        }
        return "";
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("----authHeaderSettingFilter过滤器初始化----");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain) throws IOException, ServletException {
        //log.info("经过AuthHeaderSettingFilter");
        HttpServletRequest req = (HttpServletRequest) request;
        HeaderMapRequestWrapper requestWrapper = new HeaderMapRequestWrapper(req);
        //获得请求参数中的token值
        String userId = getUserIdByToken(req);
        log.info("userId:{}", userId);
        //如果请求中带有这个参数,则进行过滤加一个header头
        requestWrapper.addHeader("userId", userId);
        chain.doFilter(requestWrapper, response); // Goes to default servlet.
    }

    @Override
    public void destroy() {
        log.info("----authHeaderSettingFilter过滤器销毁----");
    }
}

2、注册拦截器

/**
 * 拦截器配置
 */
@Configuration
public class MvcConfig implements WebMvcConfigurer {
    @Autowired
    private AuthHeaderSettingFilter authHeaderSettingFilter;

    /**
     * 配置过滤器
     *
     * @return
     */
    @Bean
    public FilterRegistrationBean filterRegistrationBean() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(authHeaderSettingFilter);
        registrationBean.addUrlPatterns("/*");
        return registrationBean;
    }

    /**
     * 定义全局http返回编码
     *
     * @param configurer
     */
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.favorParameter(true)
                // 禁用accept协商方式,即不关心前端传的accept值
                .ignoreAcceptHeader(true)
                // 哪个放在前面,哪个的优先级就高。当上面这个accept未禁用时,若请求传的accept不能覆盖下面两种,则会出现406错误
                .defaultContentType(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML)
                // 根据传参mediaType来决定返回样式
                .parameterName("mediaType")
                // 当acceptHeader未禁用时,accept的值与mediaType传参的值不一致时,以mediaType的传值为准
                // mediaType值可以不传,为空也行,但是不能是json/xml之外的其他值
                .mediaType("json", MediaType.APPLICATION_JSON)
                .mediaType("xml", MediaType.APPLICATION_XML);
    }
}

3、工具类

public class HeaderMapRequestWrapper extends HttpServletRequestWrapper {
    /**
     * construct a wrapper for this request
     *
     * @param request
     */
    public HeaderMapRequestWrapper(HttpServletRequest request) {
        super(request);
    }

    private Map<String, String> headerMap = new HashMap<String, String>();

    /**
     * add a header with given name and value
     *
     * @param name
     * @param value
     */
    public void addHeader(String name, String value) {
        headerMap.put(name, value);
    }

    @Override
    public String getHeader(String name) {
        String headerValue = super.getHeader(name);
        if (headerMap.containsKey(name)) {
            headerValue = headerMap.get(name);
        }
        return headerValue;
    }

    /**
     * get the Header names
     */
    @Override
    public Enumeration<String> getHeaderNames() {
        List<String> names = Collections.list(super.getHeaderNames());
        for (String name : headerMap.keySet()) {
            names.add(name);
        }
        return Collections.enumeration(names);
    }

    @Override
    public Enumeration<String> getHeaders(String name) {
        List<String> values = Collections.list(super.getHeaders(name));
        if (headerMap.containsKey(name)) {
            values.add(headerMap.get(name));
        }
        return Collections.enumeration(values);
    }

}

4、userId如何直接获取(@RequestHeader(“userId”)String userId)

    @PostMapping("/approval")
    public String approval(@RequestHeader("userId")String userId){
        return applyService.approval(userId);
    }
<think>好的,用户的问题是关于如何在拦截器中通过token获取userid,并希望看到示例代码。我需要先理解用户的具体需求。用户提到在Web项目中,使用token进行用户验证,当获得token后,多个地方需要根据token获取用户信息,所以想知道如何通过拦截器来实现这一点。这可能涉及到拦截器的基本概念、token的处理流程以及如何从token中提取用户信息。 首先,我应该解释拦截器的作用,尤其是在Spring框架中的Interceptor。拦截器可以在请求处理之前、之后或完成后执行代码,这里主要是在请求处理前验证token并获取userid。接下来,用户需要示例代码,所以应该提供一个简单的Java示例,使用Spring拦截器。 然后,关于token解析,可能需要使用JWT(JSON Web Token),因为这是常见的token格式,其中包含了用户信息。需要提到JWT的结构,以及如何解析其中的payload部分来获取userid。代码示例中应包括如何从请求头中获取token,验证其有效性,然后解码获取用户信息。 另外,要注意异常处理,比如token无效或过期的情况,这时应该返回401未授权的响应。同时,用户信息获取后如何传递给控制器,可以通过ThreadLocal或者请求属性来存储,这样在后续的处理中可以直接使用。 还需要考虑依赖问题,比如示例中使用了jjwt库来处理JWT,所以应该提醒用户添加相关依赖。此外,可能的安全问题,比如密钥的存储和管理,也需要简要提及,建议不要硬编码在代码中。 用户可能的问题还包括性能优化,比如缓存用户信息避免重复解析token,或者如何在不同框架中实现拦截器。因此,在相关问题部分,可以提出这些扩展问题,帮助用户深入理解。 最后,确保回答结构清晰,分步骤说明,代码示例正确,并且引用了相关参考资料,比如用户提供的引用[1]虽然主要讲token获取用户信息,但可以关联到拦截器的使用场景。</think>在Web应用中通过拦截器获取用户ID的核心流程分为三步:解析请求头获取Token、验证Token有效性、提取用户声明中的用户ID。以下是基于Spring拦截器的实现示例: ### 一、拦截器实现步骤 1. **创建拦截器类**: ```java public class AuthInterceptor implements HandlerInterceptor { private static final String SECRET_KEY = "your-secret-key"; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String token = request.getHeader("Authorization"); if (token == null || !token.startsWith("Bearer ")) { response.sendError(HttpServletResponse.SC_UNAUTHORIZED); return false; } String jwt = token.substring(7); try { Claims claims = Jwts.parser() .setSigningKey(SECRET_KEY) .parseClaimsJws(jwt) .getBody(); request.setAttribute("userId", claims.getSubject()); return true; } catch (JwtException e) { response.sendError(HttpServletResponse.SC_UNAUTHORIZED); return false; } } } ``` 2. **注册拦截器配置**: ```java @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new AuthInterceptor()) .addPathPatterns("/api/**") .excludePathPatterns("/api/login"); } } ``` ### 二、关键实现说明 1. **Token解析**:从`Authorization`请求头中提取Bearer Token[^1] 2. **JWT验证**:使用`jjwt`库验证签名和过期时间 3. **用户信息传递**:通过`request.setAttribute()`存储用户ID ### 三、控制器使用示例 ```java @RestController @RequestMapping("/api") public class UserController { @GetMapping("/profile") public ResponseEntity<?> getProfile(HttpServletRequest request) { String userId = (String) request.getAttribute("userId"); // 查询用户信息逻辑 return ResponseEntity.ok(userService.getProfile(userId)); } } ``` ### 四、注意事项 1. 密钥应存储在安全配置中,避免硬编码 2. 建议增加Token黑名单机制处理注销场景 3. 生产环境需要配置HTTPS保证传输安全 ```xml <!-- 依赖配置 --> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-api</artifactId> <version>0.11.5</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-impl</artifactId> <version>0.11.5</version> </dependency> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值