如何使用 ReactJs 将 jwt 令牌提交给 Spring Security?

Posted

技术标签:

【中文标题】如何使用 ReactJs 将 jwt 令牌提交给 Spring Security?【英文标题】:How to submit jwt token to Spring Security with ReactJs? 【发布时间】:2019-10-09 00:15:52 【问题描述】:

我已使用 Spring Security 保护了我的 Spring Boot 应用程序的 API 端点。

登录时,我生成一个新的 jwt 令牌并将其提交给用户。

在数据请求中,我希望用户在标头中提交令牌。

如果我使用邮递员执行此操作,则效果非常好。 当我尝试使用 React 发送令牌时,它失败了(axios/fetch/superagent)。 问题不在于提交令牌本身,因为如果我禁用授权,我可以使用控制器读取授权标头。

相反,当通过 React 发送标头时,Spring Security 不知何故无法识别标头。

我尝试添加另一个自定义标头以查看 Spring 是否允许这样做,但该自定义标头也被“阻止”了。

反应:

axios(apiTest, 
      async: true,
      crossDomain: true,
      method: "GET",
      headers: 
        Authorization: `Bearer $this.props.token`,
        TestHeader: "RandomValue",
        Accept: "*/*"
      ,
      processData: false,
      data: ""
    )
      .then(res => 
        if (res.data !== undefined) 
          console.log(res.data);
        
      )
      .catch(err => console.error(error));

Spring 安全性: 令牌过滤器:

@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter 

    @Value("$jwt.header")
    private String tokenHeader;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException 
                //Usual Authorization header (is null with React-use)
                final String requestHeader = request.getHeader(this.tokenHeader);
                //Custom header (null)
                System.out.println("Test Header: " + request.getHeader("TestHeader"));
        if (requestHeader != null && requestHeader.startsWith("Bearer ")) 
            String authToken = requestHeader.substring(7);
            JwtAuthentication authentication = new JwtAuthentication(authToken);
            SecurityContextHolder.getContext().setAuthentication(authentication);
        
        chain.doFilter(request, response);

    

配置:


    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter 

    @Autowired
    private JwtAuthenticationEntryPoint unauthorizedHandler;

    @Autowired
    private JwtAuthenticationProvider jwtAuthenticationProvider;

    @Autowired
    public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) 
                authenticationManagerBuilder.authenticationProvider(jwtAuthenticationProvider);
    

    @Bean
    CorsFilter corsFilter() 
        CorsFilter filter = new CorsFilter();
        return filter;
    

    @Bean
    public JwtAuthenticationTokenFilter authenticationTokenFilterBean() 
        return new JwtAuthenticationTokenFilter();
    

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception 
        httpSecurity.addFilterBefore(corsFilter(), SessionManagementFilter.class).csrf().disable().authorizeRequests()
                .antMatchers("/Login").permitAll().antMatchers("/CloseConnection**").permitAll()
                .antMatchers(HttpMethod.OPTIONS, "**").permitAll().anyRequest().authenticated().and()
                .exceptionHandling().authenticationEntryPoint(unauthorizedHandler);
    

知道具体的问题是什么以及如何解决吗?

【问题讨论】:

我面临着完全相同的问题,Postman 运行良好,但在 ReactJS/Axios 中,Authorization 永远不会被发送。 【参考方案1】:

试试这个对我有用

   private String getToken(HttpServletRequest request) 
            String header = request.getHeader("Authorization");     
            if (header != null && header.startsWith("Bearer ")) 
                return authHeader.replace("Bearer ","");
            

            return null;
        

axios 调用

axios.post(url,
     "data": 'sample',
    ,
    
      headers: 
      'Authorization':'Bearer '+token,
      'Content-Type':'application/json'
      
    )
    .then((res) => 
      console.log(res);
    )

【讨论】:

以上是关于如何使用 ReactJs 将 jwt 令牌提交给 Spring Security?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ReactJS 上使用 JWT 令牌注销

如何使用 Node、Express、Axios 在 ReactJS 前端设置带有 JWT 令牌的 cookie

如何使用 Cookie 进行存储 jwt 令牌用户认证?

ReactJS-在http请求的axios方法中将JWT令牌作为授权传递

我们如何将 JWT 令牌存储在仅限 Http 的 cookie 中?

如何从返回 axios 的响应对象访问 JWT 令牌值?