我使用Koa,Passport.js和koa-session对用户进行身份验证。 所以它基本上看起来像:
// session
var session = require('koa-session');
app.keys = [config.secret];
app.use(session());
// auth
require(__dirname+'/lib/auth'); // de/serializeUser, strategies etc..
var passport = require('koa-passport');
app.use(passport.initialize());
app.use(passport.session());
这很有效。根据请求,我确实拥有req.user
和用户ID。但是当使用套接字时,我可以这样做:
io.on('connection', function(socket) {
console.log(socket.request.headers.cookie),
});
但当然它只是加密的会话ID,我怎样才能反序列化用户并获取user.id,就像我在获取或发布请求时获得req.user
一样?
提前谢谢。
答案 0 :(得分:10)
这是一个非常晚的回复,但我希望它会对你有用。我只花了大约四个小时试图解决这个问题。
您将遇到的第一个问题是koa-session
不使用真正的会话存储。它将所有信息嵌入cookie本身,然后将其解析到客户端和从客户端解析。虽然这很方便,但在尝试合并Socket.IO
时会对您不利,因为Socket.IO
无法访问koa-session
。
您需要迁移到koa-generic-session
并使用会话商店来跟踪您的会话。在我看来,这是一个更好的举动,无论如何。我目前正在使用koa-redis
用于我的会话商店。
要在Socket.IO
中访问您的会话,您需要设置全局商店。这是我的全球商店的样子。
// store.js
var RedisStore = require('koa-redis'),
store = undefined; // global
module.exports = function(app, settings) {
// Where (app) is Koa and (settings) is arbitrary information
return (function(app, settings) {
store = store || new RedisStore();
return store;
})(app, settings);
}
之后,初始设置很简单。
// app.js
... arbitrary code here ...
var session = require('koa-generic-session');
app.keys = [config.secret];
app.use(session({
store: require('./store')(app, settings)
}));
... arbitrary code here ...
现在您已拥有全局会话存储,然后可以在Socket.IO
中访问它。请注意,您需要安装cookie
和co
模块。
// io.js
var cookie = require('cookie'),
co = require('co'),
store = require('./store')(null, settings); // We don't require the Koa app
io.use(function(socket, next){
// Now you will need to set up the authorization middleware. In order to
// authenticate, you will need the SID from the cookie generated by
// koa-generic-session. The property name is by default 'koa.sid'.
var sid = cookie.parse(socket.handshake.headers.cookie)['koa.sid'];
// We need co to handle generators for us or everything will blow up
// when you try to access data stores designed for Koa.
co(function*(){
// 'koa:sess:' is the default prefix for generic sessions.
var session = yield store.get('koa:sess:' + sid);
// At this point you can do any validation you'd like. If all is well,
// authorize the connection. Feel free to add any additional properties
// to the handshake from the session if you please.
if (session) next(null, true) // authenticated
else throw new Error('Authentication error.');
});
});
io.on('connection', function(socket){
// Access handshake here.
});
我调整了Socket.IO
v1的代码。我希望这会有所帮助。
答案 1 :(得分:0)
我使用正则表达式获取userId然后在我的数据库中找到。不是最干净的方法,但它运作良好。我只是使用koa-session-store作为我与护照js的会话。
var cookies = socket.request.headers.cookie;
var regEx = /passport"\:\{"user"\:"(.+?)"\}/g
var userIdMatches = regEx.exec(cookies);