ここでは、セッションを、リクエスト間でユーザーエージェントに関する情報を保存できるようにするいくつかの要素をまとめたものとして定義します。
ユーザーエージェントとは、デバイス(例:コンピュータのブラウザータブ、スマートフォンアプリケーション、冷蔵庫)上であなたを代表するソフトウェア(ブラウザまたはネイティブアプリケーション)のことです。これは、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は、画像、スタイルシートなどの静的アセットを指しているように見えるものを除き、すべてのリクエストに対してセッションサポートを有効にします。