セッション戦略
ユーザーがアプリケーションにアクセスする際、毎回ログインする必要がないようにしたいものです。一度ログインすれば、アプリケーションはユーザーに関するデータを保存し、次回アクセス時に中断したところから再開できるようにする必要があります。これがセッションです。Auth.jsは、主に2つのセッション戦略、JWTベースのセッションとデータベースセッションをサポートしています。
どちらのセッション戦略にも利点と欠点があり、アプリケーションの要件に基づいて評価する必要があります。
セッション戦略は、メインのAuth.js設定ファイルのsession.strategy
オプションを使用して設定できます。
JWTセッション
Auth.jsは、JSON Web Tokens (JWT)を使用してセッションを作成できます。これは、データベースプロバイダーが設定されていない限り、Auth.jsのデフォルトのセッション戦略です。ユーザーがサインインすると、JWTがHttpOnly
クッキーに作成されます。HttpOnly
にすることで、JavaScriptがクライアントサイド(例えばdocument.cookie
経由)からアクセスできなくなり、攻撃者が値を盗むのが困難になります。さらに、JWTはサーバーのみが知っている秘密鍵で暗号化されます。そのため、攻撃者がクッキーからJWTを盗んだとしても、復号することはできません。短い有効期限と組み合わせることで、JWTはセッションを作成するための安全な方法となります。
ユーザーがサインアウトすると、Auth.jsはクッキーからJWTを削除し、セッションを破棄します。
利点
- セッションとしてのJWTは、セッションの保存にデータベースを必要としません。これにより、高速化、コスト削減、スケーラビリティの向上が期待できます。
- この戦略は、追加のデータベース/サービスを管理する必要がないため、リソースの消費が少なくなります。
- 作成されたトークンを使用して、同じドメイン上のサービスとAPI間で情報をやり取りできます。データベースに問い合わせて含まれている情報を検証する必要はありません。
- JWTを使用して、サイト上で実行されているサードパーティのJavaScriptに情報を公開せずに、安全に情報を保存できます。
欠点
- エンコードされた有効期限前にJSON Web Tokenの有効期限を切らせることはできません。そのためには、無効化されたトークンのサーバーサイドのブロックリストを維持する(少なくとも実際に期限切れになるまで)必要があり、トークンが提示されるたびにリストに対してすべてのトークンをチェックする必要があります。Auth.jsはクッキーを削除しますが、ユーザーがJWTを他の場所に保存している場合、期限切れになるまで有効(サーバーはそれを受け入れます)です。(JSON Web Tokenをセッショントークンとして使用する場合、セッションをより早く無効化し、この問題を簡素化するために、より短いセッション有効期限が使用されます。)
- Auth.jsは、短いセッション有効期限によるユーザーエクスペリエンスへの悪影響を軽減するために、高度な機能を備えています。これには、自動セッショントークンローテーション、必要に応じてキープアライブメッセージ(セッションポーリング)の送信(ウィンドウまたはタブが開いている場合、短命のセッションが期限切れになるのを防ぐ)、バックグラウンド再検証、セッションの状態が変更されたり、ウィンドウまたはタブがフォーカスを獲得または失ったりするたびにウィンドウ間でセッションを同期させる自動タブ/ウィンドウ同期が含まれます。
- データベースセッショントークンと同様に、JSON Web Tokenに格納できるデータ量には制限があります。クッキーあたり約4096バイトの制限がありますが、正確な制限はブラウザーによって異なります。トークンに保存しようとするデータ量が多くなり、設定する他のクッキーが多くなるほど、この制限に近づきます。Auth.jsはセッションクッキーのチャンク化を実装しているので、4KBを超えるクッキーは分割され、解析時に再構築されます。しかし、このデータはすべてのリクエストで送信する必要があるため、この手法を使用して転送するデータ量を把握する必要があります。
- 適切に設定されていても、暗号化されたJWTに格納された情報は、いつか復号不可能であるとは限りません。例えば、欠陥の発見や技術の進歩などです。暗号化されたJSON Web Token(JWE)に格納されたデータは、いつか侵害される可能性があります。高エントロピーの秘密鍵を生成することをお勧めします。
データベースセッション
JWTセッション戦略の代わりに、Auth.jsはデータベースセッションもサポートしています。この場合、サインイン後にユーザーデータを含むJWTを保存する代わりに、Auth.jsはデータベースにセッションを作成します。セッションIDはHttpOnly
クッキーに保存されます。これはJWTセッション戦略に似ていますが、クッキーにユーザーデータを保存する代わりに、データベース内のセッションを指す不明瞭な値のみを保存します。そのため、ユーザーセッションにアクセスしようとするたびに、データベースにデータの問い合わせを行います。
ユーザーがサインアウトすると、セッションはデータベースから削除され、セッションIDはクッキーから削除されます。
利点
- データベースセッションはいつでもサーバーサイドで変更できるので、JWT戦略では困難だが不可能ではない機能(例:「すべての場所でサインアウト」、同時ログイン数の制限)を実装できます。
- Auth.jsは使用しているデータベースの種類について意見を持っていません。公式のデータベースアダプターのリストは多数ありますが、独自のアダプターを実装することもできます。
欠点
- データベースセッションはデータベースへのラウンドトリップが必要なため、接続/データベースが対応していない限り、大規模な場合に遅くなる可能性があります。
- 多くのデータベースアダプターはまだEdgeと互換性がありません。Edgeを使用すると、より高速で安価なセッション取得が可能になります。
- データベースの設定には、ステートレスなJWT戦略と比較して、より多くの労力と追加のサービス管理が必要です。