2014-10-30 10 views
5

Używam Koa, Passport.js i sesję koa do uwierzytelniania użytkowników. Wygląda to tak:Uzyskaj identyfikator użytkownika socket.io, paszport, koa

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

To działa dobrze. Na prośby mam req.user, z identyfikatorem użytkownika. Jednak przy użyciu gniazda, mogę zrobić:

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

ale oczywiście to tylko zaszyfrowany identyfikator sesji, jak mogłem deserializowania użytkownika i uzyskać user.id jak zrobić, gdy dostanę się na req.user lub wysłać zapytanie?

Z góry dziękuję.

Odpowiedz

10

Jest to odpowiedź bardzo spóźniona, ale mam nadzieję, że będzie dla ciebie przydatna. Spędziłem około czterech godzin próbując rozwiązać ten problem.

Pierwszy problem, który napotkasz, polega na tym, że koa-session nie używa prawdziwych zapisów sesji. Osadza wszystkie informacje w samym pliku cookie, a następnie analizuje je do i od klienta. Chociaż może to być wygodne, działa przeciwko tobie, próbując włączyć Socket.IO, ponieważ Socket.IO nie ma dostępu do koa-session.

Musisz przeprowadzić migrację do koa-generic-session i używać magazynu sesji do śledzenia sesji. Jest to, moim zdaniem, lepszy ruch, niezależnie. Obecnie używam koa-redis dla moich sklepów sesji. Aby uzyskać dostęp do sesji w Socket.IO, musisz mieć skonfigurowany globalny sklep. Oto, jak wygląda mój globalny sklep.

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

Po tym początkowa konfiguracja jest łatwa.

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

Teraz, że masz globalnego przechowywania sesji, można wtedy uzyskać do niego dostęp w Socket.IO. Pamiętaj, że musisz zainstalować moduły cookie i 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. 
}); 

Zmodyfikowałem kod dla Socket.IO v1. Mam nadzieję, że to pomoże.

+0

Wygląda jak Firefox (werset 36) nie wysyła plików cookie z żądaniami websocket, więc to nie zadziała. Zajmuję się rozwiązaniem, w którym obecnie strona otrzymuje token, który gniazda mogą następnie przesłać z powrotem do serwera z każdym żądaniem i może w ten sposób zostać zatwierdzony. –

+0

Wielkie dzięki, pracowali dla mnie !!! – amd

0

Użyłem wyrażeń regularnych, aby pobrać identyfikator użytkownika i znaleźć go w mojej bazie danych. Nie najczystsze podejście, ale działa dobrze. Używam tylko sesji koa-store jako mojej sesji z paszportowym js.

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