Get user ID socket.io, passport, koa

I use Koa, Passport.js and koa-session to authenticate users. So this basically looks:

// 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()); 

It works well. Upon request, I have req.user , with a user id. But when using sockets, I can do:

 io.on('connection', function(socket) { console.log(socket.request.headers.cookie), }); 

But of course, this is just an encrypted session identifier, how can I deserialize the user and get user.id the same way I do when I get req.user when I receive or send a request?

Thanks in advance.

+5
source share
2 answers

This is a very late answer, but I hope you find it useful. I just spent about four hours trying to solve this problem.

The first problem you will encounter is that koa-session does not use real session repositories. It inserts all the information into a cookie and then analyzes it from the client as well. Although this may be convenient, it works against you when you try to enable Socket.IO , because Socket.IO does not have access to koa-session .

You need to switch to koa-generic-session and use the session store to track your sessions. This, in my opinion, is the best move. I am currently using koa-redis for my session stores.

To have access to your sessions in Socket.IO , you need to set up a global store. This is what my global store looks like.

 // 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); } 

After that, the initial setup is simple.

 // 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 ... 

Now that you have the global session repository, you can access it in Socket.IO . Keep in mind that you will need to install cookie and 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. }); 

I have adjusted the code for Socket.IO v1. Hope this helps.

+10
source

I used a regex to capture userId and find it in my database. Not the cleanest approach, but it works well. I just use koa-session-store as my session with passport js.

  var cookies = socket.request.headers.cookie; var regEx = /passport"\:\{"user"\:"(.+?)"\}/g var userIdMatches = regEx.exec(cookies); 
0
source

Source: https://habr.com/ru/post/1205822/


All Articles