본문 바로가기
백엔드/Spring Boot

Spring boot + JWT + Kakao OAuth / 3편 (WebMvcConfig)

by 손정빈 2020. 11. 5.
728x90
반응형

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/

 

하나셋의 노발! 대발! 개발?

안녕하세요. 저는 서울에 상경한지 이제 3년차가 된 백엔드 개발자 하나셋이라고 합니다. 개발자로써의 삶 & 서울 생활 일대기 & 여러가지 프로그래밍 자료를 준비하여 여러분을 찾아뵙겠습니다

www.youtube.com

 

반응형

댓글