これは、Node.jsモジュールで、npmレジストリを通じて入手できます。インストールは、npm install
コマンドを使用して行います。
$ npm install express-session
var session = require('express-session')
指定されたoptions
を使用してセッションミドルウェアを作成します。
注 セッションデータは、cookie自体には保存されず、セッションIDのみが保存されます。セッションデータはサーバー側に保存されます。
注 バージョン1.5.0以降、cookie-parser
ミドルウェアは、このモジュールが機能するために使用する必要がなくなりました。このモジュールは、req
/res
でcookieを直接読み書きするようになりました。このモジュールとcookie-parser
でsecret
が同じでない場合、cookie-parser
を使用すると問題が発生する可能性があります。
警告 デフォルトのサーバーサイドセッションストレージであるMemoryStore
は、意図的に本番環境向けに設計されていません。ほとんどの条件でメモリリークが発生し、単一のプロセスを超えてスケールせず、デバッグと開発を目的としています。
ストアのリストについては、互換性のあるセッションストアを参照してください。
express-session
は、オプションオブジェクトで以下のプロパティを受け入れます。
セッションID cookieの設定オブジェクト。デフォルト値は{ path: '/', httpOnly: true, secure: false, maxAge: null }
です。
以下は、このオブジェクトで設定できるオプションです。
Domain
Set-Cookie
属性の値を指定します。デフォルトでは、ドメインは設定されておらず、ほとんどのクライアントは、cookieが現在のドメインにのみ適用されると見なします。
Expires
Set-Cookie
属性の値として使用するDate
オブジェクトを指定します。デフォルトでは、有効期限は設定されておらず、ほとんどのクライアントはこれを「非永続cookie」と見なし、Webブラウザーアプリケーションの終了のような条件で削除します。
注 オプションでexpires
とmaxAge
の両方が設定されている場合、オブジェクトで最後に定義されたものが使用されます。
注 expires
オプションは直接設定しないでください。代わりに、maxAge
オプションのみを使用してください。
HttpOnly
Set-Cookie
属性のboolean
値を指定します。真の場合、HttpOnly
属性が設定され、そうでない場合は設定されません。デフォルトでは、HttpOnly
属性が設定されています。
注 これをtrue
に設定する場合は注意が必要です。準拠したクライアントは、クライアント側のJavaScriptがdocument.cookie
でcookieを確認することを許可しません。
Expires
Set-Cookie
属性の計算時に使用するnumber
(ミリ秒単位)を指定します。これは、現在のサーバー時刻を取得し、maxAge
ミリ秒を値に追加してExpires
日時を計算することによって行われます。デフォルトでは、最大期間は設定されていません。
注 オプションでexpires
とmaxAge
の両方が設定されている場合、オブジェクトで最後に定義されたものが使用されます。
Path
Set-Cookie
の値を指定します。デフォルトでは、これはドメインのルートパスである'/'
に設定されます。
SameSite
Set-Cookie
属性の値として使用するboolean
またはstring
を指定します。デフォルトでは、これはfalse
です。
true
を設定すると、厳密な同じサイト強制のためにSameSite
属性がStrict
に設定されます。false
を設定すると、SameSite
属性は設定されません。'lax'
を設定すると、緩い同じサイト強制のためにSameSite
属性がLax
に設定されます。'none'
を設定すると、明示的なクロスサイトcookieのためにSameSite
属性がNone
に設定されます。'strict'
を設定すると、厳密な同じサイト強制のためにSameSite
属性がStrict
に設定されます。さまざまな強制レベルの詳細については、仕様を参照してください。
注 これはまだ完全に標準化されていない属性であり、将来変更される可能性があります。これは、多くのクライアントが理解するまでこの属性を無視する可能性があることも意味します。
注 ドラフト仕様では、SameSite
属性が'none'
に設定されている場合、Secure
属性をtrue
に設定する必要があることが要求されています。一部のWebブラウザーまたはその他のクライアントは、この仕様を採用している可能性があります。
Secure
Set-Cookie
属性のboolean
値を指定します。真の場合、Secure
属性が設定され、そうでない場合は設定されません。デフォルトでは、Secure
属性は設定されていません。
注 これをtrue
に設定する場合は注意が必要です。準拠したクライアントは、ブラウザーにHTTPS接続がない場合、今後cookieをサーバーに送信しません。
secure: true
は推奨オプションであることに注意してください。ただし、https対応のWebサイトが必要です。つまり、安全なcookieにはHTTPSが必要です。secure
が設定されている場合、HTTP経由でサイトにアクセスすると、cookieは設定されません。node.jsがプロキシの背後にあり、secure: true
を使用している場合は、expressで「trust proxy」を設定する必要があります。
var app = express()
app.set('trust proxy', 1) // trust first proxy
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,
cookie: { secure: true }
}))
本番環境で安全なcookieを使用し、開発環境でのテストを許可するために、以下はexpressでNODE_ENV
に基づいてこの設定を有効にする例です。
var app = express()
var sess = {
secret: 'keyboard cat',
cookie: {}
}
if (app.get('env') === 'production') {
app.set('trust proxy', 1) // trust first proxy
sess.cookie.secure = true // serve secure cookies
}
app.use(session(sess))
cookie.secure
オプションは、特別な値'auto'
に設定して、この設定が接続の決定されたセキュリティに自動的に一致するようにすることもできます。サイトがHTTPとHTTPSの両方で利用できる場合は、この設定を使用する際に注意してください。HTTPSでcookieが設定されると、HTTP経由では表示されなくなります。これは、Expressの"trust proxy"
設定が適切にセットアップされ、開発と本番環境の構成を簡素化する場合に役立ちます。
新しいセッションIDを生成するために呼び出す関数。セッションIDとして使用される文字列を返す関数を指定します。関数には、IDを生成するときにreq
に付加された値を使用する場合、最初の引数としてreq
が渡されます。
デフォルト値は、uid-safe
ライブラリを使用してIDを生成する関数です。
注 セッションが競合しないように、一意のIDを生成するように注意してください。
app.use(session({
genid: function(req) {
return genuuid() // use UUIDs for session IDs
},
secret: 'keyboard cat'
}))
応答で設定する(およびリクエストで読み取る)セッションID cookieの名前。
デフォルト値は'connect.sid'
です。
注 同じホスト名で複数のアプリを実行している場合(これは名前のみです。つまり、localhost
または127.0.0.1
です。異なるスキームとポートは異なるホスト名を示しません)、各アプリのセッションcookieを分離する必要があります。最も簡単な方法は、アプリごとに異なるname
を設定することです。
安全なcookieを設定するときに、リバースプロキシを信頼します(「X-Forwarded-Proto」ヘッダー経由)。
デフォルト値はundefined
です。
true
「X-Forwarded-Proto」ヘッダーが使用されます。false
すべてのヘッダーは無視され、直接TLS/SSL接続がある場合にのみ接続は安全であると見なされます。undefined
expressの「trust proxy」設定を使用します。リクエスト中にセッションが変更されなかった場合でも、セッションをセッションストアに保存するように強制します。ストアによってはこれが必要になる場合がありますが、クライアントがサーバーに2つの並列リクエストを行うと、競合状態が発生する可能性もあります。一方のリクエストでのセッションに対する変更は、変更を加えなかった場合でも、他のリクエストが終了したときに上書きされる可能性があります(この動作は、使用しているストアによっても異なります)。
デフォルト値はtrue
ですが、デフォルトを使用することは非推奨になりました。これは、デフォルトが将来変更されるためです。この設定について調べ、ユースケースに適したものを選択してください。通常、false
に設定します。
これがストアに必要なかどうかをどうすれば知ることができますか? 最も良い方法は、ストアがtouch
メソッドを実装しているかどうかをストアに確認することです。実装している場合は、resave: false
を安全に設定できます。touch
メソッドを実装しておらず、ストアが保存されたセッションに有効期限を設定している場合は、resave: true
が必要になる可能性があります。
すべての応答でセッション識別子cookieが設定されるように強制します。有効期限は元のmaxAge
にリセットされ、有効期限のカウントダウンがリセットされます。
デフォルト値はfalse
です。
これを有効にすると、セッション識別子cookieは、サーバーによって最後に変更されてからmaxAge
ではなく、最後の応答が送信されてからmaxAge
で期限切れになります。
これは通常、短い、セッション長ではないmaxAge
値と組み合わせて使用され、サーバーとの継続的なインタラクション中に発生する可能性を減らしながら、セッションデータを迅速にタイムアウトさせるために使用されます。
注意 このオプションがtrue
に設定されていても、saveUninitialized
オプションがfalse
に設定されている場合、初期化されていないセッションを持つレスポンスではCookieは設定されません。このオプションは、リクエストのために既存のセッションがロードされた場合にのみ動作を変更します。
「初期化されていない」セッションを強制的にストアに保存します。セッションは、新規作成されたが変更されていない場合に初期化されていないとみなされます。false
を選択することは、ログインセッションの実装、サーバーのストレージ使用量の削減、またはCookieを設定する前に許可を必要とする法律に準拠するために役立ちます。false
を選択すると、クライアントがセッションなしで複数の並列リクエストを行う場合の競合状態にも役立ちます。
デフォルト値はtrue
ですが、デフォルトの使用は非推奨になりました。デフォルトは将来変更される予定です。この設定をよく調べて、ユースケースに適したものを選択してください。
注意 SessionをPassportJSと組み合わせて使用している場合、Passportはユーザー認証後に使用するために、空のPassportオブジェクトをセッションに追加します。これはセッションへの変更として扱われ、保存される原因となります。これはPassportJS 0.3.0で修正されました
必須オプション
これは、セッションIDクッキーに署名するために使用されるシークレットです。これは、単一のシークレットの場合は文字列、複数のシークレットの場合は配列のいずれかになります。シークレットの配列が提供された場合、最初の要素のみがセッションIDクッキーに署名するために使用され、すべての要素がリクエスト内の署名を検証する際に考慮されます。シークレット自体は人間が容易に解析できるものではなく、ランダムな文字の集合が最適です。ベストプラクティスには以下が含まれる場合があります。
推測できないシークレットを使用すると、(genid
オプションによって決定される)セッションIDの推測のみにセッションをハイジャックする能力が制限されます。
シークレット値を変更すると、既存のすべてのセッションが無効になります。セッションを無効にせずにシークレットをローテーションするには、シークレットの配列を提供し、配列の最初の要素として新しいシークレットを、後の要素として以前のシークレットを含めます。
セッションストアのインスタンス。デフォルトは新しいMemoryStore
インスタンスです。
req.session
を(delete
、null
の設定などによって)unsetした場合の結果を制御します。
デフォルト値は'keep'
です。
'destroy'
レスポンスが終了するとセッションは破棄(削除)されます。'keep'
ストア内のセッションは保持されますが、リクエスト中に行われた変更は無視され、保存されません。セッションデータを保存またはアクセスするには、リクエストプロパティreq.session
を使用するだけです。これは(一般的に)ストアによってJSONとしてシリアライズされるため、ネストされたオブジェクトは通常問題ありません。たとえば、以下はユーザー固有のビューカウンターです。
// Use the session middleware
app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }}))
// Access the session as req.session
app.get('/', function(req, res, next) {
if (req.session.views) {
req.session.views++
res.setHeader('Content-Type', 'text/html')
res.write('<p>views: ' + req.session.views + '</p>')
res.write('<p>expires in: ' + (req.session.cookie.maxAge / 1000) + 's</p>')
res.end()
} else {
req.session.views = 1
res.end('welcome to the session demo. refresh!')
}
})
セッションを再生成するには、メソッドを呼び出すだけです。完了すると、新しいSIDとSession
インスタンスがreq.session
で初期化され、callback
が呼び出されます。
req.session.regenerate(function(err) {
// will have a new session here
})
セッションを破棄し、req.session
プロパティをunsetします。完了すると、callback
が呼び出されます。
req.session.destroy(function(err) {
// cannot access session here
})
ストアからセッションデータを再ロードし、req.session
オブジェクトを再設定します。完了すると、callback
が呼び出されます。
req.session.reload(function(err) {
// session updated
})
セッションをストアに保存し、ストアの内容をメモリ内の内容に置き換えます(ただし、ストアは他の動作をする可能性があります。正確な動作については、ストアのドキュメントを参照してください)。
セッションデータが変更された場合、このメソッドはHTTPレスポンスの最後に自動的に呼び出されます(ただし、この動作はミドルウェアコンストラクターのさまざまなオプションで変更できます)。このため、通常、このメソッドを呼び出す必要はありません。
リダイレクト、長時間の実行リクエスト、またはWebSocketsなど、このメソッドを呼び出すと便利な場合があります。
req.session.save(function(err) {
// session saved
})
.maxAge
プロパティを更新します。通常、セッションミドルウェアがこれを実行するため、呼び出す必要はありません。
各セッションには、関連付けられた一意のIDがあります。このプロパティはreq.sessionID
のエイリアスであり、変更することはできません。session
オブジェクトからセッションIDにアクセスできるようにするために追加されました。
各セッションには、それに付随する一意のクッキーオブジェクトがあります。これにより、訪問者ごとにセッションクッキーを変更できます。たとえば、req.session.cookie.expires
をfalse
に設定して、クッキーをユーザーエージェントの期間のみ保持できるようにすることができます。
あるいは、req.session.cookie.maxAge
は残り時間をミリ秒単位で返し、.expires
プロパティを適切に調整するために新しい値を再割り当てすることもできます。以下は実質的に同等です。
var hour = 3600000
req.session.cookie.expires = new Date(Date.now() + hour)
req.session.cookie.maxAge = hour
たとえば、maxAge
が60000
(1分)に設定され、30秒が経過した場合、現在のリクエストが完了するまで30000
が返されます。その時点で、req.session.touch()
が呼び出され、req.session.cookie.maxAge
が元の値にリセットされます。
req.session.cookie.maxAge // => 30000
req.session.cookie.originalMaxAge
プロパティは、セッションクッキーの元のmaxAge
(有効期間)をミリ秒単位で返します。
ロードされたセッションのIDを取得するには、リクエストプロパティreq.sessionID
にアクセスします。これは、セッションがロードまたは作成されたときに設定される読み取り専用の値です。
すべてのセッションストアは、EventEmitter
であり、特定のメソッドを実装する必要があります。次のメソッドは、必須、推奨、およびオプションのリストです。
実装例については、connect-redisリポジトリを参照してください。
オプション
このオプションのメソッドは、ストア内のすべてのセッションを配列として取得するために使用されます。callback
は、callback(error, sessions)
として呼び出す必要があります。
必須
この必須メソッドは、セッションID(sid
)を指定して、ストアからセッションを破棄/削除するために使用されます。callback
は、セッションが破棄されたら、callback(error)
として呼び出す必要があります。
オプション
このオプションのメソッドは、ストアからすべてのセッションを削除するために使用されます。callback
は、ストアがクリアされたら、callback(error)
として呼び出す必要があります。
オプション
このオプションのメソッドは、ストア内のすべてのセッションの数を取得するために使用されます。callback
は、callback(error, len)
として呼び出す必要があります。
必須
この必須メソッドは、セッションID(sid
)を指定して、ストアからセッションを取得するために使用されます。callback
は、callback(error, session)
として呼び出す必要があります。
session
引数は、見つかった場合はセッションである必要があり、そうでない場合は、セッションが見つからなかった(エラーが発生しなかった)場合は、null
またはundefined
である必要があります。error.code === 'ENOENT'
の場合、callback(null, null)
のように動作する特別なケースが作成されます。
必須
この必須メソッドは、セッションID(sid
)とセッション(session
)オブジェクトを指定して、セッションをストアにアップサートするために使用されます。セッションがストアに設定されたら、コールバックはcallback(error)
として呼び出す必要があります。
推奨
この推奨メソッドは、セッションID(sid
)とセッション(session
)オブジェクトを指定して、指定されたセッションを「タッチ」するために使用されます。セッションがタッチされたら、callback
はcallback(error)
として呼び出す必要があります。
これは主に、ストアがアイドル状態のセッションを自動的に削除する場合に使用され、このメソッドは、指定されたセッションがアクティブであることをストアに通知し、アイドルタイマーをリセットする可能性があります。
次のモジュールは、このモジュールと互換性のあるセッションストアを実装しています。追加のモジュールを追加するには、PRを作成してください:)
aerospike-session-store Aerospikeを使用するセッションストア。
better-sqlite3-session-store better-sqlite3に基づいたセッションストア。
cassandra-store Apache Cassandraベースのセッションストア。
cluster-store node cluster(Raspberry Pi 2やその他のマルチコア組み込みデバイスに望ましい)で、SQLite(knex経由)、leveldb、ファイル、またはメモリなどのインプロセス/組み込みストアを使用するためのラッパー。
connect-arango ArangoDBベースのセッションストア。
connect-azuretables Azure Table Storageベースのセッションストア。
connect-cloudant-store IBM Cloudantベースのセッションストア。
connect-couchbase couchbaseベースのセッションストア。
connect-datacache IBM Bluemix Data Cacheベースのセッションストア。
@google-cloud/connect-datastore Google Cloud Datastoreベースのセッションストア。
connect-db2 ibm_dbモジュールを使用して構築されたIBM DB2ベースのセッションストア。
connect-dynamodb DynamoDBベースのセッションストア。
@google-cloud/connect-firestore Google Cloud Firestoreベースのセッションストア。
connect-hazelcast ConnectおよびExpress用のHazelcastセッションストア。
connect-loki Loki.jsベースのセッションストア。
connect-lowdb lowdbベースのセッションストア。
connect-memcached memcachedベースのセッションストア。
connect-memjs memcachedクライアントとしてmemjsを使用したmemcachedベースのセッションストア。
connect-ml MarkLogic Serverベースのセッションストア。
connect-monetdb MonetDBベースのセッションストア。
connect-mongo MongoDBベースのセッションストア。
connect-mongodb-session MongoDBによって構築・メンテナンスされている、軽量なMongoDBベースのセッションストア。
connect-mssql-v2 connect-mssql をベースにした、Microsoft SQL Serverベースのセッションストア。
connect-neo4j Neo4jベースのセッションストア。
connect-pg-simple PostgreSQLベースのセッションストア。
connect-redis Redisベースのセッションストア。
connect-session-firebase Firebase Realtime Databaseに基づいたセッションストア。
connect-session-knex PostgreSQL、MySQL、MariaDB、SQLite3、およびOracle用のSQLクエリビルダーであるKnex.jsを使用したセッションストア。
connect-session-sequelize PostgreSQL、MySQL、SQLite、およびMSSQL用のNode.js / io.js ORMであるSequelize.jsを使用したセッションストア。
connect-sqlite3 TJの
connect-redis
ストアをモデルにした、SQLite3セッションストア。
connect-typeorm TypeORMベースのセッションストア。
couchdb-expression CouchDBベースのセッションストア。
dynamodb-store DynamoDBベースのセッションストア。
express-etcd etcdベースのセッションストア。
express-mysql-session node-mysqlモジュールを介してネイティブのMySQLを使用するセッションストア。
express-nedb-session NeDBベースのセッションストア。
express-oracle-session node-oracledbモジュールを介してネイティブのoracleを使用するセッションストア。
express-session-cache-manager cache-managerを実装したストア。これはさまざまなストレージタイプをサポートしています。
express-session-etcd3 etcd3ベースのセッションストア。
express-session-level LevelDBベースのセッションストア。
express-session-rsdb Rocket-Storeに基づいたセッションストア。Rocket-Storeは非常にシンプルで、超高速でありながら強力な、フラットファイルデータベースです。
express-sessions MongoDBとRedisの両方をサポートするセッションストア。
firestore-store Firestoreベースのセッションストア。
fortune-session Fortune.jsに基づいたセッションストア。 Fortuneでサポートされているすべてのバックエンド(MongoDB、Redis、Postgres、NeDB)をサポートします。
hazelcast-store Hazelcast Node Client上に構築されたHazelcastベースのセッションストア。
level-session-store LevelDBベースのセッションストア。
lowdb-session-store lowdbベースのセッションストア。
medea-session-store Medeaベースのセッションストア。
memorystore 本番環境向けに作成されたメモリセッションストア。
mssql-session-store SQL Serverベースのセッションストア。
nedb-session-store 代替のNeDBベース(インメモリまたはファイル永続化)セッションストア。
@quixo3/prisma-session-store Prisma Framework用のセッションストア。
restsession RESTful APIを利用してセッションを保存します
sequelstore-connect Sequelize.jsを使用したセッションストア。
session-file-store ファイルシステムベースのセッションストア。
session-pouchdb-store PouchDB / CouchDB用のセッションストア。 埋め込み、カスタム、またはリモートのPouchDBインスタンスとリアルタイム同期を受け入れます。
session-rethinkdb RethinkDBベースのセッションストア。
@databunker/session-store Databunkerベースの暗号化セッションストア。
sessionstore さまざまなデータベースで動作するセッションストア。
tch-nedb-session NeDBに基づいたファイルシステムセッションストア。
ユーザーのページビューを保存するためにexpress-session
を使用する簡単な例。
var express = require('express')
var parseurl = require('parseurl')
var session = require('express-session')
var app = express()
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true
}))
app.use(function (req, res, next) {
if (!req.session.views) {
req.session.views = {}
}
// get the url pathname
var pathname = parseurl(req).pathname
// count the views
req.session.views[pathname] = (req.session.views[pathname] || 0) + 1
next()
})
app.get('/foo', function (req, res, next) {
res.send('you viewed this page ' + req.session.views['/foo'] + ' times')
})
app.get('/bar', function (req, res, next) {
res.send('you viewed this page ' + req.session.views['/bar'] + ' times')
})
app.listen(3000)
ユーザーのログインセッションを維持するためにexpress-session
を使用する簡単な例。
var escapeHtml = require('escape-html')
var express = require('express')
var session = require('express-session')
var app = express()
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true
}))
// middleware to test if authenticated
function isAuthenticated (req, res, next) {
if (req.session.user) next()
else next('route')
}
app.get('/', isAuthenticated, function (req, res) {
// this is only called when there is an authentication user due to isAuthenticated
res.send('hello, ' + escapeHtml(req.session.user) + '!' +
' <a href="/logout">Logout</a>')
})
app.get('/', function (req, res) {
res.send('<form action="/login" method="post">' +
'Username: <input name="user"><br>' +
'Password: <input name="pass" type="password"><br>' +
'<input type="submit" text="Login"></form>')
})
app.post('/login', express.urlencoded({ extended: false }), function (req, res) {
// login logic to validate req.body.user and req.body.pass
// would be implemented here. for this example any combo works
// regenerate the session, which is good practice to help
// guard against forms of session fixation
req.session.regenerate(function (err) {
if (err) next(err)
// store user information in session, typically a user id
req.session.user = req.body.user
// save the session before redirection to ensure page
// load does not happen before session is saved
req.session.save(function (err) {
if (err) return next(err)
res.redirect('/')
})
})
})
app.get('/logout', function (req, res, next) {
// logout logic
// clear the user from the session object and save.
// this will ensure that re-using the old session id
// does not have a logged in user
req.session.user = null
req.session.save(function (err) {
if (err) next(err)
// regenerate the session, which is good practice to help
// guard against forms of session fixation
req.session.regenerate(function (err) {
if (err) next(err)
res.redirect('/')
})
})
})
app.listen(3000)
このモジュールは、セッション操作に関する情報をログに記録するために、内部的にdebugモジュールを使用します。
すべての内部ログを表示するには、アプリを起動するとき(この例ではnpm start
)に、DEBUG
環境変数をexpress-session
に設定します
$ DEBUG=express-session npm start
Windowsでは、対応するコマンドを使用してください。
> set DEBUG=express-session & npm start