Socket.io và Session của Express



  • E đang làm một Chat app bằng socket io và express. Qua express, e có dùng session để lưu thông tin đăng nhập và user được login bằng tài khoản Facebook.

    Bây giờ em muốn chia sẻ session giữa express và socket.io thì làm thế nào ạ.



  • @Ha-Linh
    Session thì bạn store nó vào đâu ?. Nếu vào DB thì bạn có thể kêu client lấy cookie ID và gửi lên. Dựa vào Cookie ID thì mình có thể get cái session ra và kiểm tra. Nhưng mình thấy cách này nó không good lắm. Với mobile khi giao tiếp với server sẽ hạn chế. Mình nghĩ bạn nên thử sử dụng token based để auth.

    Đại khái khi một người login (= email, =facebook, = google, ...) Thì bạn sẽ tạo cho họ một key. Store vào đâu đó trên server (Databases, ....) Sau đó gủi token đó cho client. Client sẽ tự lưu vào Local Storage , .... . Khi client làm việc với server bạn viết 1 function authenticate. Lúc này socket hay restful bạn đều phải gửi token lên để làm việc

    Đây là bài viết cách sử dụng token based với socket.io .: https://auth0.com/blog/auth-with-socket-io/

    Nguyen (Rodgers) Hien.
    Sent from Wood-PC.

    0


  • @Nguyen-Hien App của mình vốn từ mobile rồi, đã có lượng người dùng nhất định. H mình mới mở rộng ra nền web thôi. Và vấn đề không phải là bên phía client.

    Mình dùng passport để tạo login. Nhưng giờ session từ passport được sử dụng bên socket.io thế nào cơ.



  • @Ha-Linh Cái này thì mình chưa gặp với không làm nhiều với passport. Nhưng theo mình biết thì passport bạn sẽ store vào một thứ gọi là sessionStore.. Dựa vào cookieID của client. Vậy thì sẽ có cách get được. Mình kiếm thấy bài viết này không biết bạn dùng được không ~~ :
    https://stackoverflow.com/questions/13095418/how-to-use-passport-with-express-and-socket-io.

    Kéo xuống cuối có câu trả lời được tích V ấy. Nhìn khá ổn. Họ connect vào session store được.

    Nguyen (Rodgers) Hien.
    Sent from Wood-PC.

    0


  • @Ha-Linh express có thể chia sẻ với socket io bằng cách sử dụng chung http.

    var express = require('express');
    var app = express();
    var http = require('http').Server(app);
    var io = require('socket.io')(http);
    
    http.listen(8000, function() {
    	log('running on 8000');
    });
    
    app.use(... cookies...)
    app.use(... body_parser...)
    app.sessionStore = function(req,res,next){...}
    app.use(app.sessionStore)
    app.use(... passport ... )
    
    io.use(function(socket,next){
    return app.sessionStore(socket.request, socket.request.res, next);
    })
    
    io.on('connection', function(socket) {
    	// console.log(socket.request.session)
    })
    
    


  • Thank @hidemanvn rất nhiều.



  • Hi @hidemanvn

    Hiện tại mình cũng đang share session cho cả socket và http sử dụng passport để đảm bảo việc authentication cho cả http và socket.
    Vấn đề mình mới gặp là mình muốn sử dụng socket khi không login (Ví dụ khi người dùng không login, nhưng vẫn load/update data từ server về qua socket). Liệu có giải pháp nào không nhỉ?



  • @Hiep-Trinh khi không login bạn vẫn sử dụng bình thường thôi. Bạn cứ hình dung Session là cái cổng. Người đã login mới có quyền vào một số khu vực, còn người dùng chưa login vẫn được đứng ngoài nhìn vậy.



  • @hidemanvn

    Vấn đề của mình là khi login thì mới connect đc với socket. Còn khi không login thì không connect được. Bạn xem hộ mình xem config sai ở đâu
    https://codeshare.io/5OKn6x



  • @Hiep-Trinh bạn thử io.sockets.on => io.on xem.



  • @hidemanvn k đc bạn ạ



  • Bạn set fail/success callback cho module passport.socketio chưa ?

    io.use(passportSocketIo.authorize({
    	key: 'connect.sid',
    	secret: 'secret',
    	store: sessionStore,
    	passport: passport,
    	cookieParser: require('cookie-parser'),
      success: .... 
      fail:function(data, message, error, accept){
        if (error) {
          console.log(message);
            accept(null, false);
        }
      }
    }));
    ....
    io.sockets.on('connection', function(socket) {
      console.log("Connected"); // can not go here without authentication
      console.log(socket.request.user) // { logged_in: false }
    });
    


  • @hidemanvn

    Mình set fail/success callback cho passport.socketio rồi. Nếu validate err, khi không login thì hàm authorize sẽ return err :"User not authorized through passport. (User Property not found)". Dường như khi share session, nó yêu cầu tất cả phải authenticate qua passport.

    Nếu mình chỉ return accept() trong hàm fail callback thì sẽ connect được socket. Nhưng mình không chắc nó có rủi ro gì k. Mình mới làm với passport nên không rõ, bạn có ý kiến j trong trường hợp fail callback return accept() để đồng ý tất cả mọi connect k?



  • Theo mình thì không có rủi ro gì. Vì bên router của socket đã có socket.request.user để kiểm tra việc logged hay chưa. Bạn dùng params đó để điều hướng.



  • Cám ơn @hidemanvn


Log in to reply