2020/11/04 - [백엔드/Spring Boot] - Spring boot +JWT+ Kakao OAuth / 1편 (멀티모듈)
2020/11/05 - [백엔드/Spring Boot] - Spring boot + JWT+ Kakao OAuth / 2편 (Security)
이전 편에 이어서 마지막으로 WebMvcConfigSupport에 Resolver를 추가함으로써 작업한 내용을 소개하도록 하겠습니다.
WebMvcConfigSupport.class
@Configuration
class WebMvcSupportConfig(
@Value("\${jwt.header}") private val header: String,
private val jwtTokenUtils: JwtTokenUtils,
private val userRepository: UserRepository
) : WebMvcConfigurationSupport() {
@Bean
fun corsFilter(): CorsFilter? {
val source = UrlBasedCorsConfigurationSource()
val config = CorsConfiguration()
config.allowCredentials = true
config.addAllowedOrigin("*")
config.addAllowedHeader("*")
config.addAllowedMethod("*")
source.registerCorsConfiguration("/**", config)
return CorsFilter(source)
}
override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
// register swagger endpoint
registry.addResourceHandler("/swagger-ui.html**")
.addResourceLocations("classpath:/META-INF/resources/")
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/")
}
override fun addArgumentResolvers(argumentResolvers: MutableList<HandlerMethodArgumentResolver>) {
argumentResolvers.add(AuthenticationTokenResolver(header, jwtTokenUtils, userRepository))
}
}
addArgumentResolvers에 추가하는 Resovler의 경우 Controller를 통해 요청이 올 경우 request들 제 정의 할 수 있게 도와주는 역할을 합니다.
AuthenticationTokenResolver.class
class AuthenticationTokenResolver(
private val header: String,
private val jwtTokenUtils: JwtTokenUtils,
private val userRepository: UserRepository
): HandlerMethodArgumentResolver {
override fun supportsParameter(parameter: MethodParameter): Boolean {
return parameter.parameterType == AuthenticatedUser::class.java
}
override fun resolveArgument(parameter: MethodParameter, mavContainer: ModelAndViewContainer?, webRequest: NativeWebRequest, binderFactory: WebDataBinderFactory?): Any? {
val token = webRequest.getToken()
val username = jwtTokenUtils.getUsernameFromToken(token) ?: return null
val user = userRepository.findByUsernameAndActive(username) ?: return null
return AuthenticatedUser(uid = user.id, username = user.username, token = token)
}
private fun NativeWebRequest.getToken(): String {
return getHeader(header)?.substring(7) ?: ""
}
}
제가 구현한 AuthenticationTokenResolver는 선언해놓은 Controller의 메소드에 AuthenticatedUser라는 클래스가 있을 경우 적용이 되며 요청이 온 Header에서 JwtToken을 가져와 인증 후 AuthenticatedUser 클래스를 생성하여 리턴하는 역할을 합니다.
그래서 실제 작동이 되는 UserInfoController에서 확인해보시면
UserInfoController.class
@Api(tags = ["유저 정보 조회 및 수정"])
@RestController
@RequestMapping("/api/v1/user")
class UserInfoController(
private val userInfoService: UserInfoService
) : RestSupport() {
@GetMapping
@ApiImplicitParams(
ApiImplicitParam(
name = "Authorization",
value = "",
required = true,
allowEmptyValue = false,
paramType = "header",
dataTypeClass = String::class,
example = "Bearer eyJhbGciOiJIUzUxMiJ9.eyJhdXRob3JpdHkiOlt7ImF1dGhvcml0eSI6IkxFVkVMMCJ9XSwic3ViIjoia2FrYW8xNTE0NjYxOTk4IiwiYXVkIjoibW9iaWxlIiwiaWF0IjoxNjAzODY4OTg3LCJleHAiOjE2MDUzNDg5ODd9.wf8la-S_BP011E6ufCAC7eOp3nJghZ5RbuZ57GmN9vD3bkdxH2aCRSoff6FTHYZs6L9urRdXS64Z2R4kWppKhA"
)
)
@PreAuthorize("hasRole('ADMIN')")
fun getUserInfo(user: AuthenticatedUser): ResponseEntity<Any> {
userInfoService.getUserInfo(user)
return response("ok")
}
}
위 코드를 보시면 헤더에 Authorization으로 Bearer ~~~ 를 보내만 줫을뿐입니다. AuthenticatedUser이 생성이 되어서 오는걸 확인 하실수 있습니다.
여기까지 Spring boot와 Jwt Token, 카카오 소셜 로그인 (OAuth)를 이용한 회원가입 및 로그인 프로젝트를 설명해보았습니다.
혹시나 궁금하신 내용이나 질문 사항이 있으시면 댓글을 달아주세요 ㅎㅎ
또한 평일 저녁 10시부터 새벽 1시까지 공부겸 질문 받는 시간으로 유튜브에서 스트리밍 하고 있습니다.
와서 보고 궁금했던 내용같은 걸 말해주시면 좀더 자세하게 답변 드릴수 있을 것 같습니다.
감사합니다.
www.youtube.com/channel/UCR6LHBfFACFKsfFF6XMDlZA/
'백엔드 > Spring Boot' 카테고리의 다른 글
업비트 자동매매 서버 만들기 (1~3편) (2) | 2020.11.14 |
---|---|
Spring boot + JWT+ Kakao OAuth / 2편 (Security) (0) | 2020.11.05 |
Spring boot + JWT + Kakao OAuth / 1편 (멀티모듈) (1) | 2020.11.04 |
[Spring boot] @Controller 와 @RestController의 차이 (0) | 2019.10.11 |
댓글