Ktor Serverにおけるセッション認証
必須の依存関係: io.ktor:ktor-server-auth
, io.ktor:ktor-server-sessions
コード例: auth-form-session
セッションは、異なるHTTPリクエスト間でデータを永続化するメカニズムを提供します。一般的なユースケースとしては、ログイン中のユーザーIDの保存、ショッピングカートの内容、クライアント上でのユーザー設定の保持などがあります。
Ktorでは、既存の関連セッションを持つユーザーは、session
プロバイダーを使用して認証できます。たとえば、ユーザーが初めてWebフォームを使用してログインした場合、ユーザー名をクッキーセッションに保存し、その後のリクエストでsession
プロバイダーを使用してそのユーザーを認証できます。
Ktorにおける認証と認可に関する一般的な情報については、「Ktor Serverにおける認証と認可」セクションを参照してください。
依存関係の追加
session
認証を有効にするには、ビルドスクリプトに以下のアーティファクトを含める必要があります。
セッションを使用するための
ktor-server-sessions
依存関係を追加します。KotlinGroovyXML認証のための
ktor-server-auth
依存関係を追加します。KotlinGroovyXML
セッション認証フロー
セッションを使用した認証フローはさまざまであり、アプリケーションでのユーザー認証方法によって異なります。ここでは、フォームベース認証でどのように見えるかを見てみましょう。
- クライアントは(ユーザー名とパスワードを含む)Webフォームデータを含むリクエストをサーバーに送信します。
- サーバーはクライアントから送信されたクレデンシャルを検証し、ユーザー名をクッキーセッションに保存し、要求されたコンテンツとユーザー名を含むクッキーで応答します。
- クライアントは、クッキーを付けて保護されたリソースに後続のリクエストを行います。
- 受信したクッキーデータに基づき、Ktorはこのユーザーのクッキーセッションが存在するかどうかを確認し、オプションで受信したセッションデータに対して追加の検証を行います。検証が成功した場合、サーバーは要求されたコンテンツで応答します。
セッション認証のインストール
session
認証プロバイダーをインストールするには、install
ブロック内で、必要なセッション型を指定してsession関数を呼び出します。
import io.ktor.server.application.*
import io.ktor.server.auth.*
import io.ktor.server.sessions.*
//...
install(Authentication) {
session<UserSession> {
// Configure session authentication
}
}
セッション認証の設定
このセクションでは、フォームベース認証を使用してユーザーを認証し、このユーザーに関する情報をクッキーセッションに保存し、その後のリクエストでsession
プロバイダーを使用してこのユーザーを認証する方法を示します。
完全な例については、auth-form-sessionを参照してください。
ステップ1: データクラスの作成
まず、セッションデータを保存するためのデータクラスを作成する必要があります。
@Serializable
data class UserSession(val name: String, val count: Int)
ステップ2: セッションのインストールと設定
データクラスを作成したら、Sessions
プラグインをインストールして設定する必要があります。以下の例では、指定されたクッキーパスと有効期限を持つクッキーセッションをインストールし、設定します。
cookie<UserSession>("user_session") {
cookie.path = "/"
cookie.maxAgeInSeconds = 60
}
}
セッションの設定の詳細については、「セッション設定の概要」を参照してください。
ステップ3: セッション認証の設定
session
認証プロバイダーは、SessionAuthenticationProvider.Config
クラスを介してその設定を公開します。以下の例では、以下の設定が指定されています。
validate()
関数は、セッションインスタンスをチェックし、認証が成功した場合にAny
型のプリンシパルを返します。challenge()
関数は、認証が失敗した場合に実行されるアクションを指定します。例えば、ログインページにリダイレクトしたり、UnauthorizedResponse
を送信したりできます。
install(Authentication) {
session<UserSession>("auth-session") {
validate { session ->
if(session.name.startsWith("jet")) {
session
} else {
null
}
}
challenge {
call.respondRedirect("/login")
}
}
}
ステップ4: セッションへのユーザーデータの保存
ログイン中のユーザーに関する情報をセッションに保存するには、call.sessions.set()
関数を使用します。
以下の例は、Webフォームを使用したシンプルな認証フローを示しています。
authenticate("auth-form") {
post("/login") {
val userName = call.principal<UserIdPrincipal>()?.name.toString()
call.sessions.set(UserSession(name = userName, count = 1))
call.respondRedirect("/hello")
}
}
フォームベース認証フローの詳細については、フォームベース認証のドキュメントを参照してください。
ステップ5: 特定のリソースを保護する
session
プロバイダーを設定した後、authenticate()
関数を使用してアプリケーション内の特定のリソースを保護できます。
認証に成功すると、ルートハンドラ内でcall.principal()
関数を使用することで、認証されたプリンシパル(この場合はUserSession
インスタンス)を取得できます。
authenticate("auth-session") {
get("/hello") {
val userSession = call.principal<UserSession>()
call.sessions.set(userSession?.copy(count = userSession.count + 1))
call.respondText("Hello, ${userSession?.name}! Visit count is ${userSession?.count}.")
}
}
完全な例については、auth-form-sessionを参照してください。