在我的 Spring Boot 应用程序中实现 jwt auth 后,Ive cors 问题再次出现

Posted

技术标签:

【中文标题】在我的 Spring Boot 应用程序中实现 jwt auth 后,Ive cors 问题再次出现【英文标题】:after implement jwt autho in my spring boot application,Ive cors problem again 【发布时间】:2021-07-29 21:40:42 【问题描述】:

在执行 jwt 之前我对 cors 没有任何问题,但是在我执行它之后,我发现了这个 cors 错误,我不知道如何解决它:

CORS 策略已阻止从源“http://localhost:52151”访问“x”处的 XMLHttpRequest:请求的资源上不存在“Access-Control-Allow-Origin”标头。

我的后端是用 spring 构建的,并部署在 heroku 中,而我的前端是 angular。

HibernateProjectAplication:

@SpringBootApplication
public class HibernateProjectApplication extends SpringBootServletInitializer 

    public static void main(String[] args) 

        SpringApplication.run(HibernateProjectApplication.class, args);
    
    @Bean
    public WebMvcConfigurer corsConfigurer() 
        return new WebMvcConfigurer() 
            @Override
            public void addCorsMappings(CorsRegistry registry) 
                registry.addMapping("/api").allowedOrigins("*").allowedMethods("DELETE", "POST", "PUT", "GET", "OPTIONS").allowedHeaders("*");
            
        ;
    



用户控制器:

@RestController
@CrossOrigin(origins = "*")
@RequestMapping("/api")
public class UserController 

    private final userService userService;
    private final Logger log = LoggerFactory.getLogger(UserController.class);

    public UserController(userService userService) 
        this.userService = userService;
    

    @Autowired
    AuthenticationManager authenticationManager;

    @Autowired
    userRepository userRepository;

    @Autowired
    PasswordEncoder encoder;

    @Autowired
    JwtTokenUtil JwtTokenUtil;

    @PostMapping("/register")
    public ResponseEntity<User> registerUser(@RequestBody User user) 
        if (user != null) 
            User newUser = userService.createNewUser(user);
        
        return ResponseEntity.ok().body(user);
    

    @PostMapping("/login")
    public ResponseEntity<User> userLogin(@RequestBody User user) 
        Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword()));
        SecurityContextHolder.getContext().setAuthentication(authentication);

        String token = JwtTokenUtil.generateJwtToken(authentication);
        if (userService.findByEmailAndPassword(user.getEmail(), user.getPassword())) 

            User userBean = (User) authentication.getPrincipal();
        
        return ResponseEntity.ok(user);

    

WebSecurityConfig:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter 
    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http.cors().and().authorizeRequests().anyRequest().permitAll()
                .and().csrf().disable();

    
    @Bean
    public static PasswordEncoder passwordEncoder() 
        return new BCryptPasswordEncoder();
    

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception 
        return super.authenticationManagerBean();
    

    @Bean
    public CorsConfigurationSource corsConfigurationSource() 
        final CorsConfiguration configuration = new CorsConfiguration();
        configuration.addAllowedOrigin("*");
        configuration.addAllowedMethod("*");
        configuration.addAllowedHeader("*");
        configuration.setAllowCredentials(true);

        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    

JwtTokenUtil:

@Component
public class JwtTokenUtil 
    @Value("$jwttoken.secret")
    private String jwtTokenSecret;
    @Value("$jwttoken.expiration")
    private long jwtTokenExpiration;

    public String generateJwtToken(Authentication authentication) 
        User userPrincipal = (User)authentication.getPrincipal();
        return Jwts.builder()
                .setSubject(userPrincipal.getUsername())
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + jwtTokenExpiration))
                .signWith(SignatureAlgorithm.HS512, jwtTokenSecret)
                .compact();
    

    public boolean validateJwtToken(String token) 
        try 
            Jwts.parser()
                    .setSigningKey(jwtTokenSecret)
                    .parseClaimsJws(token);
            return true;
        catch(UnsupportedJwtException exp) 
            System.out.println("claimsJws argument does not represent Claims JWS" + exp.getMessage());
        catch(MalformedJwtException exp) 
            System.out.println("claimsJws string is not a valid JWS" + exp.getMessage());
        catch(SignatureException exp) 
            System.out.println("claimsJws JWS signature validation failed" + exp.getMessage());
        catch(ExpiredJwtException exp) 
            System.out.println("Claims has an expiration time before the method is invoked" + exp.getMessage());
        catch(IllegalArgumentException exp) 
            System.out.println("claimsJws string is null or empty or only whitespace" + exp.getMessage());
        
        return false;
    

    public String getUserNameFromJwtToken(String token) 
        Claims claims =Jwts.parser()
                .setSigningKey(jwtTokenSecret)
                .parseClaimsJws(token)
                .getBody();
        return claims.getSubject();

    

任何想法我该如何解决这个问题???非常感谢:)))

【问题讨论】:

【参考方案1】:

我相信您忘记在“/api”映射后添加通配符了。

@Bean
public WebMvcConfigurer corsConfigurer() 
    return new WebMvcConfigurer() 
        @Override
        public void addCorsMappings(CorsRegistry registry) 
            registry.addMapping("/api/**")
                    .allowedMethods("HEAD", "GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH")
                    .allowedHeaders("*").allowedOrigins("*").exposedHeaders(
                    "Access-Control-Allow-Origin", "Access-Control-Allow-Methods",
                    "Access-Control-Max-Age", "Access-Control-Allow-Headers");
        
    ;

【讨论】:

以上是关于在我的 Spring Boot 应用程序中实现 jwt auth 后,Ive cors 问题再次出现的主要内容,如果未能解决你的问题,请参考以下文章

在我的 Spring Boot 应用程序中实现 jwt auth 后,Ive cors 问题再次出现

如何在 Spring Boot 中实现刷新令牌

如何使用hibernate在spring boot中实现分页

在spring boot中实现自己的内存缓存机制

在 Spring Boot 中实现“注销”功能

如何在spring boot中实现用户级别的特定授权?