ここでは、セッションを、リクエスト間でユーザーエージェントに関する情報を保存できるようにするいくつかの要素をまとめたものとして定義します。
ユーザーエージェントとは、デバイス(例:コンピュータのブラウザータブ、スマートフォンアプリケーション、冷蔵庫)上であなたを代表するソフトウェア(ブラウザまたはネイティブアプリケーション)のことです。これは、Cookieまたはアクセストークンと1対1で関連付けられます。
セッションは、リクエスト/レスポンスのサイクルがステートレスであるため、非常に役立ちます。リクエスト/レスポンスのサイクルがステートレスであると見なされるのは、クライアントもサーバーも、特定のリクエストに関する異なるリクエスト間で情報を本質的に保存しないためです。したがって、リクエスト/レスポンスのライフサイクルは、リクエスト元のユーザーエージェントへのレスポンス(例:res.send())が行われたときに終了します。
注:ここでは、ブラウザのユーザーエージェントのコンテキストでセッションについて説明します。Sailsでセッションを好きなように使用できますが、一般的にはユーザーエージェント認証の状態を保存するためだけに使用するのが最善の方法です。認証とは、ユーザーエージェントが特定のIDを持っていることを証明できるプロセスです。たとえば、保護された機能にアクセスするには、自分のブラウザータブが実際にデータベースの特定のユーザーレコードに対応していることを証明する必要がある場合があります。一意の名前とパスワードを提供すると、名前を調べて、(おそらく暗号化された)パスワードと自分のパスワードを比較できます。一致すれば、認証されます。しかし、リクエスト間でその「認証済み」の状態をどのように保存するのでしょうか?そこでセッションが登場します。
Sailsでのセッションの実装には、主に3つの要素があります。
sails.sid)を保存するCookieセッションストアは、メモリ内(これはSailsのデフォルトのセッションストアです)またはデータベース内(Sailsにはこの目的でRedisを使用するための組み込みサポートがあります)のいずれかになります。Sailsは、Connectミドルウェアの上に構築されてセッションを管理します。これには、ユーザーエージェントにセッションID(sid)を保存するためにCookieを使用することも含まれます。
リクエストがSailsに送信されると、リクエストヘッダーはセッションミドルウェアによって解析されます。
ヘッダーにCookieが含まれていない場合、sidがセッションで作成され、デフォルトのセッションディクショナリがreq(例:req.session)に追加されます。この時点で、セッションプロパティ(通常はコントローラー/アクション内)に変更を加えることができます。たとえば、次のログインアクションを見てみましょう。
module.exports = {
login: function(req, res) {
// Authentication code here
// If successfully authenticated
req.session.userId = foundUser.id; // returned from a database
return res.json(foundUser);
}
}
ここでは、req.sessionにuserIdプロパティを追加しました。
注:プロパティは、レスポンスが送信されるまでセッションストアに保存されず、他のリクエストでも利用できません。
レスポンスが送信されると、新しいリクエストはreq.session.userIdにアクセスできるようになります。リクエストヘッダーにCookieがなかったため、Cookieが作成されます。
Sails.sidを含むCookieがある場合次に、ユーザーエージェントが次のリクエストを行うと、Cookieに保存されているSails.sidの信頼性がチェックされます。セッションストアに既存のsidと一致する場合は、セッションストアの内容がreqディクショナリ(req.session)のプロパティとして追加されます。req.sessionのプロパティ(例:req.session.userId)にアクセスしたり、プロパティを設定したりできます(例:req.session.userId == someValue)。セッションストアの値は変更される可能性がありますが、Sails.sidとsidは通常変更されません。
Sails.sidはいつ変更されますか?開発中、Sailsのセッションストアはメモリ内にあります。したがって、Sailsサーバーを閉じると、現在のセッションストアは消えます。Sailsが再起動されると、ユーザーエージェントのリクエストにCookie内のSails.sidが含まれていても、sidはセッションストアには存在しなくなります。したがって、新しいsidが生成され、Cookieで置き換えられます。ユーザーエージェントのCookieが期限切れになった場合、または削除された場合も、Sails.sidは変更されます。
SailsのCookieの有効期間は、デフォルト設定(期限切れなし)から、
projectName/config/session.jsのcookie.maxAgeプロパティにアクセスして新しい設定に変更できます。
Redisは、Sailsインスタンスとは別のセッションストアとして使用できるキーバリューデータベースパッケージです。セッションのこの構成には、2つの利点があります。1つ目は、Sailsを再起動してもセッションストアが存続することです。2つ目は、ロードバランサーの背後に複数のSailsインスタンスがある場合、すべてのインスタンスが単一の統合セッションストアを指すことができることです。
開発環境でRedisをセッションストアとして有効にするには、まず、ローカルマシンでRedisインスタンスが実行されていることを確認します(redis-server)。次に、sails lift --redisでアプリを起動します。
これは、sails lift --session.adapter=@sailshq/connect-redis --sockets.adapter=@sailshq/socket.io-redisのショートカットにすぎません。これらのパッケージは、新しいSailsアプリの依存関係としてデフォルトで含まれていますが、アップグレードされたアプリを使用している場合は、npm install @sailshq/connect-redisおよびnpm install @sailshq/socket.io-redisを実行する必要があります。
この組み込み構成では、ローカルのRedisインスタンスを使用していることに注意してください。高度なセッション構成オプションについては、リファレンス > 構成 > sails.config.sessionを参照してください。
Cookieの値は、まず構成可能なシークレット(単なる長い文字列)でsidをハッシュすることによって作成されます。
projectName/config/session.jsでセッションのsecretプロパティを変更できます。
Sailsのsid(例:Sails.sid)は、平文のsidと、sidとsecretのハッシュの組み合わせになります。抽象的な世界から取り出すために、例を使用してみましょう。Sailsは234lj232hg234jluy32UUYUHHのsidと9238cca11a83d473e10981c49c4fのsession secretを作成します。これらの値は、Sailsが組み合わせてハッシュし、AuSosBAbL9t3Ev44EofZtIpiMuV7fB2oiのsignatureを作成する2つの文字列にすぎません。したがって、Sails.sidは234lj232hg234jluy32UUYUHH.AuSosBAbL9t3Ev44EofZtIpiMuV7fB2oiになり、レスポンスヘッダーにset-cookieプロパティを送信することによって、ユーザーエージェントのCookieに保存されます。
これは何を防止しますか?これにより、ユーザーがsidを推測することを防ぎます。また、悪意のあるユーザーが、悪意のあるユーザーが知っているsidを使用して認証リクエストを偽造することを防ぎます。これにより、悪意のあるユーザーがセッションを通じてユーザーが認証されている間にsidを使用して不正な操作を行う可能性があります。
Sailsアプリがトースターなどのブラウザ以外のクライアントからアクセスするように設計されている場合でも、認証にはセッションを使用することを強くお勧めします。理解するのが複雑な場合もありますが、Sailsの組み込みセッションメカニズム(セッションストア+ HTTP専用Cookie)は、一般的に壊れにくく、使いやすく、自分で何かをロールアウトするよりもリスクが低い実績のあるソリューションです。
とは言え、セッションが常にオプションになるとは限りません(たとえば、JWTのような別の認証スキームと統合する必要がある場合など)。これらの場合、アプリ全体またはリクエストごとにセッションを無効にすることができます。
アプリのセッションサポートを完全にオフにするには、.sailsrcファイルに以下を追加します。
"hooks": {
"session": false
}
これにより、コアSailsセッションフックが無効になります。sails_hooks__session環境変数をfalseに設定することでもこれを実現できます。
ルートごと(またはリクエストごと)にセッションサポートをオフにするには、sails.config.session.isSessionDisabled設定を使用します。デフォルトでは、Sailsは、画像、スタイルシートなどの静的アセットを指しているように見えるものを除き、すべてのリクエストに対してセッションサポートを有効にします。