cookie-session

NPM Version NPM Downloads Build Status Test Coverage

シンプルな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

API

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
}))

cookieSession(options)

指定されたオプションで新しいCookieセッションミドルウェアを作成します。このミドルウェアは、ロードされたセッションを表すオブジェクトを提供するsessionプロパティをreqにアタッチします。このセッションは、リクエストに有効なセッションが提供されていない場合は新しいセッション、リクエストからロードされたセッションのいずれかです。

req.sessionの内容が変更された場合、ミドルウェアは自動的にレスポンスにSet-Cookieヘッダーを追加します。注記 セッションにコンテンツがない限り、レスポンスにSet-Cookieヘッダーは含まれず(そのため、特定のユーザーに対してセッションは作成されません)、セッションを保存する識別情報が得られたらすぐにreq.sessionに何かを追加してください。

オプション

Cookieセッションは、オプションオブジェクトに次のプロパティを受け入れます。

name

設定するCookieの名前。デフォルトはsessionです。

keys

Cookieの値に署名および検証するために使用するキーのリスト、または設定済みのKeygripインスタンス。設定されたCookieには常にkeys[0]で署名されますが、他のキーは検証に有効であり、キーのローテーションが可能です。Keygripインスタンスが提供されている場合、署名アルゴリズムなどの署名パラメーターを変更するために使用できます。

secret

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)。

req.session

指定されたリクエストのセッションを表します。

.isChanged

リクエスト中にセッションが変更された場合はtrueです。

.isNew

セッションが新しい場合はtrueです。

.isPopulated

セッションにデータが設定されているか空かどうかを判別します。

req.sessionOptions

現在のリクエストのセッションオプションを表します。これらのオプションは、ミドルウェアの構築時に提供されたもののシャローコピーであり、リクエストごとに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の制限を超えないほど小さかった古いセッション情報が使用されることになります。

セッションオブジェクトがこれらの制限に達していることがわかった場合は、セッション内のデータをブラウザとの各リクエストで送受信する代わりに、サーバー上のデータベースからロードする必要があるかどうかを検討することをお勧めします。または、代替のセッション戦略に移行してください。

ライセンス

MIT