Role seu próprio armazenamento de sessão para Node.js / Express

Se você estiver usando Node.js com Express para construir projetos web genéricos , terá que resolver, mais cedo ou mais tarde, a questão do armazenamento de dados da sessão.

Manter as sessões na memória é obviamente uma má ideia por vários motivos (vazamentos de memória, problemas de clustering / simultaneidade, etc.).

Além disso, há outro motivo pelo qual você deve prestar atenção especial a este assunto: presumindo que seu site seja público e tenha milhares de páginas / URLs, os bots de indexação do Google / Bing provavelmente farão muitas solicitações tentando descobrir o que está lá, especialmente depois de enviar seu sitemap.xml ( nota: gerar um sitemap.xml usando o mecanismo de modelo Jade é muito fácil ).

Infelizmente, os bots de indexação não mantêm cookies, então cada uma dessas dezenas de milhares de solicitações provavelmente irá acionar sua própria sessão, então o armazenamento da sessão pode acabar muito grande se você não tomar cuidado .

Armazenamento de sessão em Node.js / Express

Embora existam, é claro, vários módulos npm por aí (como este ), se você quiser controle total sobre o que está acontecendo lá, ou se estiver apenas procurando manter as dependências em um mínimo, implementando suas próprias solução baseada em Connect-middleware prova ser uma tarefa bastante fácil.

Veja como você poderia fazer isso, supondo que já esteja usando o Mongoose para persistir seus dados no MongoDB (> 2.2 para o recurso de coleções TTL ):

models/session.coffee:

mongoose = require 'mongoose'

schema
= new mongoose.Schema

_id
: String

data
:
type
: mongoose.Schema.Types.Mixed
required
: yes

usedAt
:
type
: Date
expires
: process.env.SESSION_TTL * 3600

,

versionKey
: no

model
= mongoose.model 'Session', schema
module.exports = model

helpers/session-store.coffee:

Session = require '../models/session'

noop
= ->

module.exports = (connect) ->
class SessionStore extends connect.session.Store

get: (_id, cb) ->
Session.findById(_id).lean().exec (err, session) ->
return cb err if err
cb
null, session?.data

set: (_id, data, cb = noop) ->
return Session.remove { _id }, cb unless data
Session.update { _id }, { data, usedAt: new Date }, { upsert: yes }, cb

destroy
: (_id, cb = noop) ->
Session.remove { _id }, cb

app.coffee:

express        = require 'express'
http
= require 'http'
mongoose
= require 'mongoose'

SessionStore = require('./helpers/session-store') express

# other imports, etc...

env
= process.env

mongoose
.connect env.MONGODB_URI, { db: { native_parser: yes } }

app
= express()

# various middleware

app
.use express.session
secret
: env.SESSION_KEY
cookie
:
maxAge
: env.SESSION_TTL * 3600000
store
: new SessionStore

# Set-up routes...

# Start listening
http
.createServer(app).listen app.get('port'), ->
console
.log "Express server listening on port #{app.get('port')}"

E não se esqueça de definir a variável de ambiente SESSION_TTL para o número de horas que você deseja manter as sessões vivas por …