シンプルなCookieベースのセッションミドルウェアです。
ユーザーセッションは、Cookieを使用して主に2つの方法で保存できます。サーバー上またはクライアント上です。このモジュールは、セッションデータをCookie内にクライアント側に保存しますが、express-sessionのようなモジュールは、セッション識別子のみをCookie内にクライアント側に保存し、セッションデータをサーバー側(通常はデータベース)に保存します。
どちらを使用するかを選択する際に役立つ点を以下に示します。
cookie-session
はサーバー側にデータベース/リソースを必要としませんが、合計セッションデータはブラウザの最大Cookieサイズを超えることはできません。cookie-session
は、特定のロードバランスシナリオを簡素化できます。cookie-session
を使用して「軽量」セッションを保存し、データベースバックアップのセカンダリストアを検索するための識別子を含めることで、データベースのルックアップを減らすことができます。注記 このモジュールは、Cookie内のセッションコンテンツを暗号化しません。改ざんを防ぐための署名のみを提供します。クライアントは、Cookieの値を調べるとセッションデータを読み取ることができます。秘密データは、暗号化せずにreq.session
に設定しないでください。または、代わりにサーバー側のセッションを使用してください。
注記 このモジュールは、セッションの再生を防ぎません。設定されている有効期限はCookieのみの有効期限です。これがアプリケーションの懸念事項である場合は、req.session
オブジェクトに有効期限を保存し、サーバー上で検証し、アプリケーションのニーズに合わせてセッションを拡張するためのその他のロジックを実装できます。
これは、Node.jsモジュールであり、npmレジストリを介して利用できます。npm install
コマンドを使用してインストールします。
$ npm install cookie-session
var cookieSession = require('cookie-session')
var express = require('express')
var app = express()
app.use(cookieSession({
name: 'session',
keys: [/* secret keys */],
// Cookie Options
maxAge: 24 * 60 * 60 * 1000 // 24 hours
}))
指定されたオプションで新しいCookieセッションミドルウェアを作成します。このミドルウェアは、ロードされたセッションを表すオブジェクトを提供するsession
プロパティをreq
にアタッチします。このセッションは、リクエストに有効なセッションが提供されていない場合は新しいセッション、リクエストからロードされたセッションのいずれかです。
req.session
の内容が変更された場合、ミドルウェアは自動的にレスポンスにSet-Cookie
ヘッダーを追加します。注記 セッションにコンテンツがない限り、レスポンスにSet-Cookie
ヘッダーは含まれず(そのため、特定のユーザーに対してセッションは作成されません)、セッションを保存する識別情報が得られたらすぐにreq.session
に何かを追加してください。
Cookieセッションは、オプションオブジェクトに次のプロパティを受け入れます。
設定するCookieの名前。デフォルトはsession
です。
Cookieの値に署名および検証するために使用するキーのリスト、または設定済みのKeygrip
インスタンス。設定されたCookieには常にkeys[0]
で署名されますが、他のキーは検証に有効であり、キーのローテーションが可能です。Keygrip
インスタンスが提供されている場合、署名アルゴリズムなどの署名パラメーターを変更するために使用できます。
keys
が提供されていない場合、単一のキーとして使用される文字列。
その他のオプションは、cookies.get()
とcookies.set()
に渡され、セキュリティ、ドメイン、パス、署名などの設定を制御できます。
オプションには、次のいずれかを含めることもできます(完全なリストについては、cookiesモジュールのドキュメントを参照してください)。
maxAge
: 有効期限までのミリ秒数を表す数値 (Date.now()
からのミリ秒数)expires
: Cookieの有効期限を示すDate
オブジェクト(デフォルトではセッションの終了時に有効期限切れになります)。path
: Cookieのパスを示す文字列(デフォルトは/
)。domain
: Cookieのドメインを示す文字列(デフォルトなし)。sameSite
: Cookieが「same site」Cookieかどうかを示すブール値または文字列(デフォルトはfalse
)。これは'strict'
、'lax'
、'none'
、またはtrue
('strict'
にマップされます)に設定できます。secure
: CookieがHTTPS経由でのみ送信されるかどうかを示すブール値(HTTPの場合はデフォルトでfalse
、HTTPSの場合はデフォルトでtrue
)。これがtrue
に設定されていて、Node.jsがTLS接続を直接経由していない場合は、プロキシの背後にあるExpressの設定方法を確認してください。Cookieが正しく設定されない可能性があります。httpOnly
: CookieがHTTP(S)経由でのみ送信され、クライアント側のJavaScriptで使用できないかどうかを示すブール値(デフォルトはtrue
)。signed
: Cookieに署名するかどうかを示すブール値(デフォルトはtrue
)。overwrite
: 同じ名前の以前に設定されたCookieを上書きするかどうかを示すブール値(デフォルトはtrue
)。指定されたリクエストのセッションを表します。
リクエスト中にセッションが変更された場合はtrue
です。
セッションが新しい場合はtrue
です。
セッションにデータが設定されているか空かどうかを判別します。
現在のリクエストのセッションオプションを表します。これらのオプションは、ミドルウェアの構築時に提供されたもののシャローコピーであり、リクエストごとにCookieの設定動作を変更するために変更できます。
セッションを破棄するには、単にnull
に設定します。
req.session = null
セッションの全内容はクライアント側のCookieに保持されるため、セッションはSet-Cookie
レスポンスヘッダーにCookieを書き込むことで「保存」されます。これは、Node.jsのレスポンスヘッダーがクライアントに書き込まれ、セッションが破棄されなかった場合に、セッションに変更が加えられた場合に自動的に行われます。
var cookieSession = require('cookie-session')
var express = require('express')
var app = express()
app.set('trust proxy', 1) // trust first proxy
app.use(cookieSession({
name: 'session',
keys: ['key1', 'key2']
}))
app.get('/', function (req, res, next) {
// Update views
req.session.views = (req.session.views || 0) + 1
// Write response
res.end(req.session.views + ' views')
})
app.listen(3000)
var cookieSession = require('cookie-session')
var express = require('express')
var app = express()
app.set('trust proxy', 1) // trust first proxy
app.use(cookieSession({
name: 'session',
keys: ['key1', 'key2']
}))
// This allows you to set req.session.maxAge to let certain sessions
// have a different value than the default.
app.use(function (req, res, next) {
req.sessionOptions.maxAge = req.session.maxAge || req.sessionOptions.maxAge
next()
})
// ... your logic here ...
このモジュールは、セッションの内容が変更されていない場合は、Set-Cookie
ヘッダーを送信しません。つまり、ユーザーのブラウザでセッションの有効期限を延長するには(たとえば、ユーザーアクティビティに応じて)、セッションへの何らかの変更を行う必要があります。
var cookieSession = require('cookie-session')
var express = require('express')
var app = express()
app.use(cookieSession({
name: 'session',
keys: ['key1', 'key2']
}))
// Update a value in the cookie so that the set-cookie will be sent.
// Only changes every minute so that it's not sent with every request.
app.use(function (req, res, next) {
req.session.nowInMinutes = Math.floor(Date.now() / 60e3)
next()
})
// ... your logic here ...
この例では、キーと追加の署名設定を提供するために、keys
オプションとしてカスタムKeygrip
インスタンスを作成する方法を示しています。
var cookieSession = require('cookie-session')
var express = require('express')
var Keygrip = require('keygrip')
var app = express()
app.use(cookieSession({
name: 'session',
keys: new Keygrip(['key1', 'key2'], 'SHA384', 'base64')
}))
// ... your logic here ...
セッションオブジェクト全体がエンコードされてCookieに保存されるため、さまざまなブラウザで最大Cookieサイズ制限を超える可能性があります。RFC6265仕様は、ブラウザがするべきであることを推奨しています。
Cookieあたり少なくとも4096バイト(Cookieの名前、値、属性の長さの合計で測定)。
実際には、この制限はブラウザによってわずかに異なります。ブラウザの制限のリストはこちらを参照してください。経験則として、ドメインあたり4093バイトを超えないようにしてください。
セッションオブジェクトがエンコード時にブラウザの制限を超えるほど大きい場合、ほとんどの場合、ブラウザはCookieの保存を拒否します。これにより、ブラウザからの次のリクエストで、a)セッション情報がないか、b)Cookieの制限を超えないほど小さかった古いセッション情報が使用されることになります。
セッションオブジェクトがこれらの制限に達していることがわかった場合は、セッション内のデータをブラウザとの各リクエストで送受信する代わりに、サーバー上のデータベースからロードする必要があるかどうかを検討することをお勧めします。または、代替のセッション戦略に移行してください。