如何配置具有多个会话的 express 和 passport

How to configure express and passport with multiple sessions

我需要实现一个 HTTP 服务器,它支持使用护照进行单独的会话处理。原因是我需要对 2 个实体进行身份验证:我的客户(帐户)和他们的客户(用户),我的想法是为此使用自己的安全 "space":自己的会话中间件、不同的会话属性、自己的护照实例.

如果我只为帐户使用会话存储而不为使用此代码的用户使用它,它工作正常:

const express = require('express')
const session = require('express-session')
const Passport = require('passport').Passport
const userPassport = new Passport()
const accountPassport = new Passport()
// add passport strategies

const app = express()
app.use(session({
  secret: config.session.secret,
  //store: accountSessionStore,
  resave: true,
  saveUninitialized: true,
}))

app.use(accountPassport.initialize({ userProperty: 'account' }))
app.use(accountPassport.session())

app.use(userPassport.initialize({ userProperty: 'user' }))

当我在末尾添加这一行 app.use(userPassport.session()) 时,它就中断了:帐户的登录流程不再有效。似乎 express session 中间件无法处理多个 passport 实例,最后一次调用正在覆盖实例。

像这样将帐户和客户包装到自己的实例中:

const app1 = express()
// register stuff for accounts
const app2 = express()
// register stuff for users
const rootApp = express()
rootApp.use(app1)
rootApp.use(app2)

没有用,使用自己的 HTTP 服务器(和一个额外的端口)似乎有点矫枉过正。

我认为 passport 在初始化时将其实例附加到请求,因此您观察到这种行为是有道理的。

我有类似的任务,我通过创建两个 Passport 实例和两个路由器解决了它 (express.js 4.x)。

然后你可以单独配置每个会话,将不同的通行证附加到不同的路由。

咖啡脚本中的例子,希望能给你一个线索:

#
# Apps
#

app                 = express()
adminApp            = express()

#
# Routers
#

apiRouter           = express.Router()
adminRouter         = express.Router()

#
# Authentication
#
apiPassport         = new Passport()
adminPassport       = new Passport()

#
# Add API auth strategies
# 
apiPassport.use new AnonymousStrategy()
adminPassport.use new new TwitterStrategy # ...

adminPassport.serializeUser (user, done) ->
  done null, user.id
  return

adminPassport.deserializeUser (id, done) ->
  done null, id: id
  return

#
# Configure session
# 
app.use '/api/v1/auth*', session({
  name: 'sid',
  saveUninitialized: false,
  resave: false,
  secret: process.env.SESSION_SECRET || 'keyboard cat',
  store: new MongoStore(mongooseConnection: mongoose.connection)
})

adminApp.use session({
  name: 'admin.sid',
  saveUninitialized: false,
  resave: false,
  secret: process.env.SESSION_SECRET || 'keyboard cat',
  store: new MongoStore(mongooseConnection: mongoose.connection)
})

#
# Configure passport middleware
# 
app.use '/api*', apiPassport.initialize()
app.use '/api*', apiPassport.session()

adminApp.use adminPassport.initialize()
adminApp.use adminPassport.session()

#
# Mount apps and routers
#

adminApp.use adminRouter
app.use '/api/v1/', apiRouter
app.use '/admin/', adminApp