如何在服务器重新启动时使用通行证存储已连接的用户?
How to store connected users with passport across server reboot?
我在玩passport-local
。它的使用非常简单,但是 passport 在 cookie-session-id 和连接的用户之间建立关系的方式对我来说仍然很神秘。
我想将连接的会话存储在数据库中,以便:
- 了解连接的用户
- 检测 IP 更改(出于安全原因)
- 自动断开长时间未见的用户
- 更改每个请求的会话号(出于安全原因)
- 在服务器重启后保持用户连接(对调试和服务器更新很有用)
从下面这个不起作用的片段中,您可以看到我有两个集合:
- 一个存储注册用户
- 一个用来存储连接的用户
这里是片段:
import passport from 'passport'
import LocalStrategy from 'passport-local'
import mongoose from 'mongoose'
var UserSchema = new mongoose.Schema({
username: String,
password: String
})
var Sessions = new mongoose.Schema({
session: String, // Sessions of connected users
username: { type: Schema.Types.ObjectId, ref: 'User' },
ip: String, // IP of the connected user
lastSeen: Date, // When the user made his last request
})
var User = mongoose.model('UserSchema')
我应该如何使用 passport
填充会话 table?
嗯,我想我明白了,我应该可以回答我自己的问题了。
护照无罪
Passport 不负责持久性,但 express.session
负责。 Passport 在 中间件 中添加了一个包装器来拦截 HTTP 请求并使用 LogOut
或 username
等方法和属性填充请求。
默认情况下 express.session
将数据存储到内存中,因此当服务器停止时这些数据将被销毁。 Passport 仅将一个字段存储到会话中:
{ passport: { user: 'user-id' }}
现在我们证明了 Passport,我们可以专注于会话。
会话数
Express session 会自动创建一个带有签名 sid
的 cookie,该 cookie 由秘密制成:
app.use(express.session({
秘密:'keyboard cat'
})
这个 sid
是 cookie id,它被 express.session
到 link 会话数据(仅存储在服务器上)与来自客户端的请求一起使用。
持久会话
要实现您想做的事情(...我想做的事情),您必须使会话持久化。如果要使用 MongoDB,可以使用 connect-mongo
将会话数据存储到 Mongo 集合中:
const MongoStore = require('connect-mongo')(express.session);
var app = express();
app.configure(function() {
app.use(express.session({
secret: 'keyboard cat',
rolling: true,
store: new MongoStore({ url: 'mongodb://localhost/db', stringify: false })
}));
//...
}
当您启动服务器并且有人发出请求时,它会在数据库集合中添加一个条目:
{
"_id" : "AcBXmfIXvz_y2Jp4nw1zfJvZTVPsCq7D",
"session" : {
"cookie" : {
"originalMaxAge" : null,
"expires" : null,
"secure" : null,
"httpOnly" : true,
"domain" : null,
"path" : "/"
},
"passport" : {
"user" : NumberInt(1)
}
},
"expires" : ISODate("2018-06-03T18:10:54.237+0000")
}
您可以看到 Passport 仅按照说明存储用户 ID。
总结
Know the connected users
现在,您在 MongoDB 中有了这些信息。然而,当用户断开连接时,数据会话将保留在数据库中。您可以使用兼容模式:
app.use(session({
store: new MongoStore({
url: 'mongodb://localhost/test-app',
autoRemove: 'interval',
autoRemoveInterval: 10 // In minutes. Default
})
}));
自动从数据库中删除过期的会话。
Detect IP changes (for security reasons)
您必须将此信息存储到您的会话中:
req.session.ip = (req.headers['x-forwarded-for'] ||
req.connection.remoteAddress ||
req.socket.remoteAddress ||
req.connection.socket.remoteAddress).split(",")[0];
Auto disconnect users not seen for a long time
您必须手动实施。您可以使用 MongoStore 中的 event
,例如在触摸会话时触发的 touch
。
Change the session number across each request (for security reasons)
这个比较复杂,我还没有答案。跨连接更改 cookie sid
意味着重新生成新的会话 ID 并更新 MongoDB。我还没有有效的解决方案。
Keep the users connected across server reboot (useful for debugging, and server update)
好吧,感谢 connect-mongo
我在玩passport-local
。它的使用非常简单,但是 passport 在 cookie-session-id 和连接的用户之间建立关系的方式对我来说仍然很神秘。
我想将连接的会话存储在数据库中,以便:
- 了解连接的用户
- 检测 IP 更改(出于安全原因)
- 自动断开长时间未见的用户
- 更改每个请求的会话号(出于安全原因)
- 在服务器重启后保持用户连接(对调试和服务器更新很有用)
从下面这个不起作用的片段中,您可以看到我有两个集合:
- 一个存储注册用户
- 一个用来存储连接的用户
这里是片段:
import passport from 'passport'
import LocalStrategy from 'passport-local'
import mongoose from 'mongoose'
var UserSchema = new mongoose.Schema({
username: String,
password: String
})
var Sessions = new mongoose.Schema({
session: String, // Sessions of connected users
username: { type: Schema.Types.ObjectId, ref: 'User' },
ip: String, // IP of the connected user
lastSeen: Date, // When the user made his last request
})
var User = mongoose.model('UserSchema')
我应该如何使用 passport
填充会话 table?
嗯,我想我明白了,我应该可以回答我自己的问题了。
护照无罪
Passport 不负责持久性,但 express.session
负责。 Passport 在 中间件 中添加了一个包装器来拦截 HTTP 请求并使用 LogOut
或 username
等方法和属性填充请求。
默认情况下 express.session
将数据存储到内存中,因此当服务器停止时这些数据将被销毁。 Passport 仅将一个字段存储到会话中:
{ passport: { user: 'user-id' }}
现在我们证明了 Passport,我们可以专注于会话。
会话数
Express session 会自动创建一个带有签名 sid
的 cookie,该 cookie 由秘密制成:
app.use(express.session({
秘密:'keyboard cat'
})
这个 sid
是 cookie id,它被 express.session
到 link 会话数据(仅存储在服务器上)与来自客户端的请求一起使用。
持久会话
要实现您想做的事情(...我想做的事情),您必须使会话持久化。如果要使用 MongoDB,可以使用 connect-mongo
将会话数据存储到 Mongo 集合中:
const MongoStore = require('connect-mongo')(express.session);
var app = express();
app.configure(function() {
app.use(express.session({
secret: 'keyboard cat',
rolling: true,
store: new MongoStore({ url: 'mongodb://localhost/db', stringify: false })
}));
//...
}
当您启动服务器并且有人发出请求时,它会在数据库集合中添加一个条目:
{
"_id" : "AcBXmfIXvz_y2Jp4nw1zfJvZTVPsCq7D",
"session" : {
"cookie" : {
"originalMaxAge" : null,
"expires" : null,
"secure" : null,
"httpOnly" : true,
"domain" : null,
"path" : "/"
},
"passport" : {
"user" : NumberInt(1)
}
},
"expires" : ISODate("2018-06-03T18:10:54.237+0000")
}
您可以看到 Passport 仅按照说明存储用户 ID。
总结
Know the connected users
现在,您在 MongoDB 中有了这些信息。然而,当用户断开连接时,数据会话将保留在数据库中。您可以使用兼容模式:
app.use(session({
store: new MongoStore({
url: 'mongodb://localhost/test-app',
autoRemove: 'interval',
autoRemoveInterval: 10 // In minutes. Default
})
}));
自动从数据库中删除过期的会话。
Detect IP changes (for security reasons)
您必须将此信息存储到您的会话中:
req.session.ip = (req.headers['x-forwarded-for'] ||
req.connection.remoteAddress ||
req.socket.remoteAddress ||
req.connection.socket.remoteAddress).split(",")[0];
Auto disconnect users not seen for a long time
您必须手动实施。您可以使用 MongoStore 中的 event
,例如在触摸会话时触发的 touch
。
Change the session number across each request (for security reasons)
这个比较复杂,我还没有答案。跨连接更改 cookie sid
意味着重新生成新的会话 ID 并更新 MongoDB。我还没有有效的解决方案。
Keep the users connected across server reboot (useful for debugging, and server update)
好吧,感谢 connect-mongo