Kotlin, Auth with JWT 2장

git source 샘플소스 링크

대충 다만들고 나니.. 순서대로 어떻게 해야할지를 까먹어 모든 소스 첨부

인터셉터에 토큰 검증 해보기

SampleAuthInterceptor.class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

class SampleAuthInterceptor(
val tokenService: SampleTokenService
) : HandlerInterceptor {

companion object {

val HEADER_NAME = "X-token"

}


private val HEADER_NAME = "X-token"

override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean {
if (handler !is HandlerMethod) return true
val handlerMethod = handler

if(!handlerMethod.hasMethodAnnotation(SampleAuthorization::class.java))
return true

val token = request.getHeader(HEADER_NAME)

token?.let {
tokenService.decodeToken(it)
}?: throw RuntimeException("없으면 앙대유")
return true
}
}
  1. handlerMethod.hasMethodAnnotation(SampleAuthorization::class.java)
    해당 메소드에 SampleAuthorization어노테이션이 붙어있는지 없는지?

  2. 있을경우에는 토큰 검증

  3. token없으면 안됨 팅겨버림

어노테이션을 만들어보자

어노테이션을 만들기전에 아래의 링크 필수 참고

kotlin annotation 링크

ava annotations are 100% compatible with Kotlin ( 기존 자바 하시던 분들은 이해하는데 문제가 전혀 없음 )

SampleAuthorization

1
2
3
4
5
6

@Target(AnnotationTarget.FUNCTION)
@Retention(RetentionPolicy.RUNTIME)
annotation class SampleAuthorization(
val data: Int = 0
)

위의 interceptor를 등록하자

SampleAuthConfig.class

1
2
3
4
5
6
7
8
9
10
11
12


@Configuration
class SampleAuthConfig(
val tokenService: SampleTokenService
) : WebMvcConfigurer {


override fun addInterceptors(registry: InterceptorRegistry) {
registry.addInterceptor(SampleAuthInterceptor(tokenService))
}
}
  1. InterceptorRegistry에 직접 구현한 SampleAuthInterceptor를 등록 또는 추가
  2. 정상작동

테스트를 해보자

  • 예를 들어 토큰이 있어야만 볼수 있는 유저의 정보가 있다고 가정하였을 때 아래와같이 정보를 제공한다
  • SampleAuthorization를 붙임으로서 위의 토큰 검증

AuthController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

@RestController
@RequestMapping("/auth")
class AuthController{



@SampleAuthorization
@RequestMapping("/test")
fun testGetInfo(): String {


return "success"
}


}

테스트 진행

  1. header 에 토큰이 없을 경우

    1
    2
    3
    4
    5
    6
    7
    {
    "timestamp": "2019-09-08T08:24:31.358+0000",
    "status": 500,
    "error": "Internal Server Error",
    "message": "없으면 앙대유",
    "path": "/auth/test"
    }
  2. 이상한 토큰이 있을 경우

1
2
3
4
5
6
7
8

{
"timestamp": "2019-09-08T08:30:51.329+0000",
"status": 500,
"error": "Internal Server Error",
"message": "The token was expected to have 3 parts, but got 1.",
"path": "/auth/test"
}
  1. 정상일 경우
    success리턴

마치며

  1. jwt와 auth를 꼭 스프링 시큐리티 없이도 간단하게 구현 할수 있다.
  2. 스프링 시큐리티는 해도해도 어렵다. 그래서 위처럼 샘플 코드를 만들어보았다.
  3. 에러가 발생시 위처럼 뜨는데 이상하지 않나요? -> 직접 runtimeExeption을 상속받아 자신만의 Exception객체 생성하여 던지고 RestControllerAdvice에서 처리