JWT (JSON Web Tokens) による認証ざっくりまとめ
JWTとは?
- JSON Web Token(JWT)は、インターネット上で情報を安全に交換するためのデータ形式
- JWTは、JSON形式のデータにデジタル署名(JWS)を施すことで、情報の正当性と改ざんされていないことを保証する(情報を隠す技術はJWE(JSON Web Encryption)と呼ばれる別のもの)
- 送信者は秘密鍵で署名(JWS)し、受信者は公開鍵でその署名を検証することで、情報が信頼できることを確認する
- 署名により、情報の内容は公開されているが、その真正性は保証される
- JWTは、IDプロバイダーによるシングルサインオン機能で広く利用されている。IDフェデレーションでは、IDプロバイダーが認証したJWTを他サイトが検証し受け入れることで、ユーザーが複数のサービスを同じ認証情報で利用できるようになる。このときのJWTは「IDトークン」とも呼ばれる。
送信側の行うこと
- 情報(クレーム)をJSON形式で作成する。
- 作成した情報に対して、秘密鍵や公開鍵/秘密鍵ペアを使ってデジタル署名を行う。
- 署名されたJSONデータ(JWT)を受信側に送信する。
受信側の行うこと
- 送信側から受け取ったJWTを受け取る。
- JWTに含まれるデジタル署名を検証するために、公開鍵を使用する(秘密鍵で署名された場合)。
- 署名が有効であれば、JWTの中の情報(クレーム)が正しいと認識し、使用する。
- 署名が無効であれば、情報が信頼できないと判断し、無視またはエラー処理を行う。
JWTによる認証
認証の流れ
-
ユーザーがログイン画面にアクセス
アプリケーションのログイン画面にユーザーがアクセス
-
ログイン情報の送信
ユーザーはユーザーIDとパスワードを入力し、サーバーに送信
-
JWTの生成
サーバーはログイン情報を検証し、正しい場合にJWTを生成。このJWTにはユーザーの識別情報や有効期限などが含まれる。
-
JWTの送信と保存
サーバーは生成したJWTをユーザーに送り返し、フロントエンド(ブラウザなど)は受け取ったJWTをCookieに保存
-
再アクセス時のJWTの使用
ユーザーが再度アプリケーションにアクセスする際、ブラウザは保存されたJWTを自動的にサーバーに送信
-
JWTの検証
サーバーは送られてきたJWTを検証し、有効であればユーザーを認証する。JWTが無効である場合は、ログインが必要
-
リフレッシュトークンの使用
JWTの有効期限が切れていた場合、リフレッシュトークンがあればそれを使って新しいJWTを取得することができる。リフレッシュトークンは、通常、JWTとは別に管理され、より長い有効期限を持っている。
-
JWTの更新または再ログイン
リフレッシュトークンが無効であるか、存在しない場合は、ユーザーは再度ログイン情報を入力して新しいJWTを取得する必要がある。
リフレッシュトークン
リフレッシュトークンは、新しいアクセストークン(JWT)を取得するために使用されるため、これが漏洩すると攻撃者がユーザーの認証情報を不正に利用する可能性があり、リフレッシュトークンを保護するためにも、以下のセキュリティ属性を設定することが推奨される。
-
HttpOnly属性
この属性を設定することで、リフレッシュトークンがクライアントサイドのスクリプトによってアクセスされることを防ぐ。これにより、XSS攻撃によるトークンの盗難を防ぐことができる。
-
Secure属性
この属性を設定することで、リフレッシュトークンがHTTPSを通じてのみ送信されるようになる。これにより、中間者攻撃(MITM)によるトークンの傍受を防ぐことができる。
-
SameSite属性
Lax または Strict を設定することで、リフレッシュトークンがクロスサイトリクエストとともに送信されることを制限できる。これにより、CSRF攻撃を防ぐことができる。
この仕組みを使うメリット
- アプリケーション側でユーザーの認証情報を管理する必要がなくなる
- データベースへのアクセスが不要になるため、認証処理が高速化
- JWTをリクエストごとに送信し検証することで、ユーザーを安全に識別でき、セッションを使ってユーザー情報を保持する必要がない
- IDプロバイダーを利用することで、ユーザーは異なるサービス間でのログインの手間を省くことができ、サービスプロバイダーはIDプロバイダーの認証基盤を利用することで、セキュリティの向上とユーザー体験の改善を図ることができる。
Discussion