๋ฐ์ํ
์ด ํฌ์คํธ๋ ๋ฐ์ด ํ๋ก๊ทธ๋๋ฐ๋์ ์ ํ๋ธ ๊ฐ์๋ฅผ ๋ฃ๊ณ ๋์ ์ ๋ฆฌํ ๊ธ์ ๋๋ค.
dependency ์ถ๊ฐ
- Maven
<!-- https://mvnrepository.com/artifact/com.auth0/java-jwt -->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.16.0</version>
</dependency>
- Gradle
// https://mvnrepository.com/artifact/com.auth0/java-jwt
implementation group: 'com.auth0', name: 'java-jwt', version: '3.16.0'
application.yml ์ค์
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: "jdbc:mysql://localhost:3306/JwtTutorial"
username: "root"
password: "1234"
jpa:
hibernate:
ddl-auto: create
database: mysql
show-sql: true
jpa, db ์ค์ ๋ง๊ณ ๋ ๋ฑํ ํด์ค๊ฑด ์๋ค..
User ์์ฑ
@Data
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class User {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
@Enumerated(EnumType.STRING)
private USER_ROLES roles;
}
USER_ROLES
public enum USER_ROLES {
ROLE_ADMIN, ROLE_USER
}
SecurityConfig
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CorsFilter corsFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) // Session์ ์ฌ์ฉํ์ง ์๊ณ , Stateless ์๋ฒ๋ฅผ ๋ง๋ค๊ฒ ๋ค๋ ์๋ฏธ
.and()
.addFilter(corsFilter) // Cross-Origin ์ ์ฑ
์ฌ์ฉ X ๋ชจ๋ ์์ฒญ ํ์ฉ ** @CrossOrigin๊ณผ์ ์ฐจ์ด์ : @CrossOrigin์ ์ธ์ฆ์ด ์์ ๋ ๋ฌธ์ , ๊ทธ๋์ ์ง์ ์ํ๋ฆฌํฐ ํํฐ์ ๋ฑ๋ก!
.formLogin().disable()
.httpBasic().disable()
.authorizeRequests()
.antMatchers("/api/v1/user/**")
.hasAnyRole("USER", "MANAGER", "ADMIN")
.antMatchers("/api/v1/manager/**")
.hasAnyRole("MANAGER", "ADMIN")
.antMatchers("/api/v1/admin/**")
.hasRole("ADMIN")
.anyRequest().permitAll()
;
}
}
- csrf().disable() : ๊ณต๊ฒฉ์๊ฐ ์ฌ์ฉ์๊ฐ ์๋์น ์์ ์์ฒญ(csrf)์ ์ํํ๊ฒ ํ๋ ๊ฒ์ disableํ๋ค.
- sessionManagement().sessionCreationPolicy(SessionCreatationPolicy.STATLESS) : Session์ ์ฌ์ฉํ์ง ์๊ณ , ์๋ฒ๋ฅผ Statelessํ๊ฒ ๊ตฌ์ฑํ๊ฒ ๋ค๋ ์๋ฏธ
- formLogin(), httpBasic() : disable
"/api/v1/user/**"
๋ก ๋ค์ด์ค๋ ๋ชจ๋ ์์ฒญ์USER, MANAGE, ADMIN
๊ถํ์ด ์์ด์ผ ํ๋ค."/api/v1/manager/**"
๋ก ๋ค์ด์ค๋ ๋ชจ๋ ์์ฒญ์MANAGE, ADMIN
๊ถํ์ด ์์ด์ผ ํ๋ค."/api/v1/admin/**"
๋ก ๋ค์ด์ค๋ ๋ชจ๋ ์์ฒญ์ADMIN
๊ถํ์ด ์์ด์ผ ํ๋ค.- ๊ทธ ์ธ ๋๋จธ์ง ์์ฒญ์ ๋ชจ๋ ํ์ฉํ๋ค.
CorsConfig
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true); // ๋ด ์๋ฒ๊ฐ ์๋ต์ ํ ๋ ์๋ตํด์ค json์ ์๋ฐ์คํฌ๋ฆฝํธ์์ ์ฒ๋ฆฌํ ์ ์๊ฒ ํ ์ง๋ฅผ ์ค์
config.addAllowedOrigin("*"); // ๋ชจ๋ ip์ ์๋ต ํ์ฉ
config.addAllowedHeader("*"); // ๋ชจ๋ header์ ์๋ต ํ์ฉ
config.addAllowedMethod("*"); // ๋ชจ๋ HTTP Method ์์ฒญ ํ์ฉ
source.registerCorsConfiguration("/api/**", config); // /api/** ๋ก ๋ค์ด์ค๋ ๋ชจ๋ ์์ฒญ๋ค์ config๋ฅผ ๋ฐ๋ฅด๋๋ก ๋ฑ๋ก!
return new CorsFilter(source);
}
}
CORS(Cross-Origin Resource Sharing)
: ์ฝ๊ฒ ๋งํด ๋๋ฉ์ธ์ด ๋ค๋ฅธ ์๋ฒ๋ก ๋ฆฌ์์ค ์์ฒญ์ ๋ณด๋ด๋ฉด CORS ์ ์ฑ ์ ์๋ฐํ๊ธฐ ๋๋ฌธ์ ์๋ฌ ๋ฐ์!- ํด๊ฒฐ ๋ฐฉ๋ฒ ?
CorsConfiguration
๊ฐ์ฒด๋ฅผ ์์ฑํ์ฌ, ์ํ๋ ์์ฒญ์ ๋ํด์ ํ์ฉ์ ํด์ฃผ๋ฉด ๋ฉ๋๋ค.HTTP OPTION
์ผ๋ก ๋จผ์ ์๋น ์์ฒญ์ ๋ณด๋ด๊ณ , ์๋ฒ์์ ์์ฒญ์ ํ์ฉํ๋ค๋ ์๋ต์ ๋ฐ์ผ๋ฉด ๊ทธ๋GET or POST
๋ก ์ํ๋ ๋ฆฌ์์ค ์์ฒญ์ ๋ณด๋ด๋ ๋ฐฉ๋ฒ์ด๋ค. (์๋ต)
๋ฐ์ํ