2014-10-30 18 views
5

Tôi đang sử dụng Koa, Passport.js và koa-session để xác thực người dùng. Vì vậy, về cơ bản nó trông giống như:Nhận id người dùng socket.io, hộ chiếu, 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()); 

Điều này hoạt động tốt. Theo yêu cầu, tôi có req.user, với id người dùng. Nhưng khi sử dụng ổ cắm, tôi có thể làm:

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

Nhưng tất nhiên nó chỉ ID phiên mã hóa, làm thế nào tôi có thể deserialize người sử dụng và nhận được user.id giống như tôi làm khi tôi nhận được req.user trên nhận hoặc gửi yêu cầu?

Cảm ơn bạn trước.

Trả lời

10

Đây là phản hồi rất muộn nhưng tôi hy vọng nó sẽ được sử dụng cho bạn. Tôi chỉ mất khoảng bốn giờ để giải quyết vấn đề này.

Vấn đề đầu tiên bạn sẽ gặp phải là koa-session không sử dụng các cửa hàng phiên thực. Nó nhúng tất cả thông tin vào chính cookie và sau đó phân tích nó đến và từ máy khách. Trong khi điều này có thể thuận tiện, nó hoạt động chống lại bạn khi cố gắng kết hợp Socket.IO, vì Socket.IO không có quyền truy cập vào koa-session.

Bạn cần di chuyển đến koa-generic-session và sử dụng cửa hàng phiên để theo dõi phiên của mình. Đây là, theo ý kiến ​​của tôi, một động thái tốt hơn bất kể. Tôi hiện đang sử dụng koa-redis cho các cửa hàng phiên của tôi.

Để có quyền truy cập vào phiên của bạn trong Socket.IO, bạn sẽ cần phải thiết lập cửa hàng toàn cầu. Đây là những gì cửa hàng toàn cầu của tôi trông như thế nào.

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

Sau đó, thiết lập ban đầu thật dễ dàng.

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

Bây giờ bạn có một lưu trữ phiên toàn cầu, bạn có thể sau đó truy cập nó trong Socket.IO. Xin lưu ý rằng bạn sẽ cần cài đặt các mô-đun cookieco.

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

Tôi đã điều chỉnh mã cho Socket.IO v1. Tôi hi vọng cái này giúp được.

+0

Có vẻ như Firefox (v. 36) không gửi cookie có yêu cầu websocket, vì vậy điều này sẽ không hoạt động ở đó. Tôi đang xem xét một giải pháp hiện tại, nơi trang web nhận được một mã thông báo rằng các ổ cắm sau đó có thể gửi lại cho máy chủ với mỗi yêu cầu và có thể bởi những phương tiện được xác nhận. –

+0

Rất cám ơn, đã làm việc cho tôi !!! – amd

0

Tôi đã sử dụng regex để lấy userId và tìm thấy trong cơ sở dữ liệu của mình. Không phải là cách tiếp cận sạch sẽ nhất nhưng nó hoạt động tốt. Tôi chỉ sử dụng koa-session-store làm phiên của tôi với js hộ chiếu.

var cookies = socket.request.headers.cookie; 
    var regEx = /passport"\:\{"user"\:"(.+?)"\}/g 
    var userIdMatches = regEx.exec(cookies); 
Các vấn đề liên quan