Skip to content

Ktor 서버의 베어러 인증

필요한 의존성: io.ktor:ktor-server-auth

코드 예시: auth-bearer

네이티브 서버
Ktor는 Kotlin/Native를 지원하며 추가 런타임이나 가상 머신 없이 서버를 실행할 수 있습니다.
지원: ✅

베어러(Bearer) 인증 스키마는 접근 제어 및 인증에 사용되는 HTTP 프레임워크의 일부입니다. 이 스키마는 베어러 토큰이라고 불리는 보안 토큰을 포함합니다. 베어러 인증 스키마는 OAuth 또는 JWT의 일부로 사용되지만, 베어러 토큰을 인증하기 위한 사용자 정의 로직을 제공할 수도 있습니다.

Ktor의 인증에 대한 일반 정보는 Ktor 서버의 인증 및 권한 부여 섹션에서 확인할 수 있습니다.

베어러 인증은 HTTPS/TLS를 통해서만 사용해야 합니다.

의존성 추가

bearer 인증을 활성화하려면 빌드 스크립트에 ktor-server-auth 아티팩트를 포함해야 합니다.

Kotlin
Groovy
XML

베어러 인증 흐름

일반적으로 베어러 인증 흐름은 다음과 같습니다.

  1. 사용자가 성공적으로 인증 및 접근 권한을 부여한 후, 서버는 클라이언트에게 접근 토큰을 반환합니다.
  2. 클라이언트는 Bearer 스키마를 사용하여 Authorization 헤더에 토큰을 전달하여 보호된 리소스에 요청을 할 수 있습니다.
    HTTP
    GET http://localhost:8080/
    Authorization: Bearer abc123
  3. 서버는 요청을 수신하고 토큰을 검증합니다.
  4. 검증 후, 서버는 보호된 리소스의 내용으로 응답합니다.

베어러 인증 설치

bearer 인증 프로바이더를 설치하려면 install 블록 내에서 bearer 함수를 호출합니다.

kotlin
import io.ktor.server.application.*
import io.ktor.server.auth.*
// ...
install(Authentication) {
    bearer {
        // Configure bearer authentication
    }
}

선택적으로 지정된 라우트를 인증하는 데 사용될 수 있는 프로바이더 이름을 지정할 수 있습니다.

베어러 인증 설정

Ktor에서 다양한 인증 프로바이더를 설정하는 방법에 대한 일반적인 아이디어를 얻으려면 인증 설정을 참조하세요. 이 섹션에서는 bearer 인증 프로바이더의 설정 세부 사항을 살펴보겠습니다.

1단계: 베어러 프로바이더 설정

bearer 인증 프로바이더는 BearerAuthenticationProvider.Configuration 클래스를 통해 설정을 노출합니다. 아래 예제에서는 다음 설정이 지정되어 있습니다.

  • realm 속성은 WWW-Authenticate 헤더에 전달될 realm을 설정합니다.
  • authenticate 함수는 클라이언트가 보낸 토큰을 확인하고, 인증 성공 시 UserIdPrincipal을 반환하거나 인증 실패 시 null을 반환합니다.
kotlin
install(Authentication) {
    bearer("auth-bearer") {
        realm = "Access to the '/' path"
        authenticate { tokenCredential ->
            if (tokenCredential.token == "abc123") {
                UserIdPrincipal("jetbrains")
            } else {
                null
            }
        }
    }
}

2단계: 특정 리소스 보호

bearer 프로바이더를 설정한 후, authenticate 함수를 사용하여 애플리케이션의 특정 리소스를 보호할 수 있습니다. 인증 성공 시, 라우트 핸들러 내에서 call.principal 함수를 사용하여 인증된 UserIdPrincipal을 검색하고 인증된 사용자의 이름을 가져올 수 있습니다.

kotlin
routing {
    authenticate("auth-bearer") {
        get("/") {
            call.respondText("Hello, ${call.principal<UserIdPrincipal>()?.name}!")
        }
    }
}