05-15 08:39
Recent Posts
Recent Comments
관리 메뉴

miinsun

[Lehgo] Spring CORS 였λ₯˜ ν•΄κ²° 방법 λ³Έλ¬Έ

Project/2022 Lehgo

[Lehgo] Spring CORS 였λ₯˜ ν•΄κ²° 방법

miinsun 2022. 4. 5. 17:09

πŸ’» μ‹€μŠ΅ ν™˜κ²½

OS: AWS Linux

 

πŸ’¬ μš”ꡬ 사항

cors μ—λŸ¬λŠ” λ³΄μ•ˆ μƒμ˜ 이유둜, λΈŒλΌμš°μ €μ—μ„œ ꡐ차 좜러의 HTTP μš”μ²­μ„ μ œν•œν•˜κΈ° λ•Œλ¬Έμ— μΌμ–΄λ‚˜λŠ” μ—λŸ¬μ΄λ‹€. μ™ΈλΆ€ APIλ₯Ό μ‚¬μš©ν•˜λŠ” μ›Ή μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ€ λ³΄μ•ˆμƒμ˜ 이유 λ•Œλ¬Έμ— μžμ‹ μ˜ μΆœμ²˜μ™€ λ™μΌν•œ λ¦¬μ†ŒμŠ€λ§Œ 뢈러올 수 있으며, λ‹€λ₯Έ 좜처의 λ¦¬μ†ŒμŠ€λ₯Ό 뢈러였렀면 κ·Έ μΆœμ²˜μ—μ„œ μ˜¬λ°”λ₯Έ cors 헀더λ₯Ό ν¬ν•¨ν•œ 응닡을 λ°˜ν™˜ν•΄μ€˜μ•Ό ν•œλ‹€.

μœ„μ™€ 같은 이유둜 spring μ„œλ²„μ™€ vue μ„œλ²„μ˜ ν†΅μ‹ μ—μ„œ cors 였λ₯˜κ°€ 생겨 springμ—μ„œ corsλ₯Ό ν—ˆμš©ν•΄μ£Όλ„λ‘ μ½”λ“œλ₯Ό μˆ˜μ •ν•΄μ€˜μ•Όν•œλ‹€. 이λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ κ΅¬κΈ€λ§ν–ˆμ„ λ•Œ, 크게 3가지 방법을 μ‚¬μš©ν•  수 μžˆλŠ” κ±Έ μ•Œκ²Œ 됐닀.

1. main λ©”μ„œλ“œμ—μ„œ cors ν—ˆμš©ν•˜κΈ°
2. webConfig.java νŒŒμΌμ„ μƒˆλ‘œ λ§Œλ“€μ–΄μ„œ μ›Ή μ„€μ • ν•΄μ£ΌκΈ°
3. Spring Security μ„€μ • μˆ˜μ •ν•˜κΈ° (채택)

μœ„ 1, 2 방법이 잘 ν†΅ν•˜μ§€ μ•Šμ•˜κ³ , 우리 ν”„λ‘œμ νŠΈλŠ” spring securityλ₯Ό μ΄μš©ν•΄μ„œ 3번 λ°©λ²•μœΌλ‘œ cors 였λ₯˜λ₯Ό ν•΄κ²°ν•  수 μžˆμ—ˆλ‹€.

 

πŸ“Œ SpringSecurity μ„€μ • λ³€κ²½

Security μ„€μ • νŒŒμΌμ— cors 섀정을 μ μš©ν•΄μ£Όμž.

(1)  cors preflight μ„€μ • : Preflight request에 λŒ€ν•΄, 인증을 ν•˜μ§€ μ•Šκ³  λͺ¨λ“  μš”μ²­μ„ ν—ˆμš©ν•œλ‹€.

(2) cors().μ •μ±… μ„€μ •

import org.springframework.web.cors.CorsUtils;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http
    .csrf().disable()
    .httpBasic().disable()
    .authorizeRequests()
    <!-- (1) preflight -->
    .requestMatchers(CorsUtils::isPreFlightRequest).permitAll() 
    .antMatchers("/login").permitAll()
    .antMatchers("/exists/**").permitAll() //쀑볡 μ—¬λΆ€ 검사
    .antMatchers("/checkUser").hasRole("USER")
    .antMatchers("/admin/**").hasRole("ADMIN")
    .anyRequest().permitAll()
    .and() 
    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
    .and() 
    .formLogin()
    .disable()
    <!-- (2) cors μ„€μ • 적용 -->
    .cors().and(); 

    http.addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider), UsernamePasswordAuthenticationFilter.class);
}

 

πŸ“Œ CorsConfigurationSource λ©”μ„œλ“œ μΆ”κ°€

Security μ„€μ • νŒŒμΌμ— CorsConfigurationSource λ©”μ„œλ“œλ₯Ό μΆ”κ°€ν•΄μ£Όμž.

        • configuration.addAllowedOriginPattern("*");
          • νŠΉμ • νŒ¨ν„΄μ˜ origin으둜 λΆ€ν„° μ˜€λŠ” κ²ƒλ§Œ ν—ˆμš©ν•œλ‹€.
        • configuration.addAllowedMethod("*");
          • νŠΉμ • λ©”μ†Œλ“œλ§Œ ν—ˆμš©ν•œλ‹€.
        • configuration.addAllowedHeader("*");
          • νŠΉμ • ν—€λ”λ§Œ ν—ˆμš©ν•œλ‹€.
        • configuration.addExposedHeader("authorization");
          • μΆ”κ°€ 헀더, μ»€μŠ€ν…€ 헀더λ₯Ό μ§€μ •ν•œλ‹€.
          • jwtToken을 μ΄μš©ν•΄ μ‚¬μš©μž 인증을 ν•˜κΈ° μœ„ν•΄ 'authorization'μ΄λΌλŠ” μ»€μŠ€ν…€ 헀더가 ν•„μš”ν•˜λ‹€.
        • source.registerCorsConfiguration("/**", configuration);
          • corsConfiguration 등둝

 

// CORS ν—ˆμš© 적용
@Bean
public CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.addAllowedOriginPattern("*");
    configuration.addAllowedMethod("*");
    configuration.addAllowedHeader("*");
    configuration.addExposedHeader("authorization");
    configuration.setAllowCredentials(true);
    configuration.setMaxAge(3600L);
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
}

 

Comments