OAuthはGoogleやFacebookなどの外部プロバイダを使った安全な認証メカニズムを定義しています。 OAuthを読めばより詳細について知れます。 KtorにはOAuth 1aと2.0で動作するFeatureがあります。
シンプルなOAuth 2.0によるワークフロー:
clientId
と有効なリダイレクト先URLを指定した上で、特定プロバイダ(Google, Facebook, Twitter, Github)の認証URLへリダイレクトされます。clientId
に紐づくclientSecret
を使って認証トークンを生成します。clientSecret
で署名された認証トークン付きでリダイレクトされます。OAuthAccessTokenResponse
の生成を行います。例:
@Location("/login/{type?}") class login(val type: String = "")
val loginProviders = listOf(
OAuthServerSettings.OAuth2ServerSettings(
name = "github",
authorizeUrl = "https://github.com/login/oauth/authorize",
accessTokenUrl = "https://github.com/login/oauth/access_token",
clientId = "***",
clientSecret = "***"
)
).associateBy {it.name}
install(Authentication) {
oauth("gitHubOAuth") {
client = HttpClient(Apache)
providerLookup = { loginProviders[application.locations.resolve<login>(login::class, this).type] }
urlProvider = { url(login(it.name)) }
}
}
routing {
authenticate("gitHubOAuth") {
location<login>() {
param("error") {
handle {
call.loginFailedPage(call.parameters.getAll("error").orEmpty())
}
}
handle {
val principal = call.authentication.principal<OAuthAccessTokenResponse>()
if (principal != null) {
call.loggedInSuccessResponse(principal)
} else {
call.loginPage()
}
}
}
}
}
OAuthバージョンによって、異なるPrincipalが取得されます。
sealed class OAuthAccessTokenResponse : Principal {
data class OAuth1a(
val token: String, val tokenSecret: String,
val extraParameters: Parameters = Parameters.Empty
) : OAuthAccessTokenResponse()
data class OAuth2(
val accessToken: String, val tokenType: String,
val expiresIn: Long, val refreshToken: String?,
val extraParameters: Parameters = Parameters.Empty
) : OAuthAccessTokenResponse()
}