Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use loopback token for authentication of socket.io

I'm working with loopback 2.0 and socket.io 1.0.6.

I'd like to use loopback authentication method for authentication of socket.io.

I found the method to authenticate users in loopback/lib/middleware/token.js. https://github.com/strongloop/loopback/blob/master/lib/middleware/token.js

Then I write like below:

var loopback = require('loopback');
var ioapp = module.exports = socketio;

function socketio(server) {
  var io = require('socket.io')(server);

  // auth
  io.use(function(socket, next) {
    loopback.token()(socket.request, null, next);
  });

  // listeners
  ...

  return io;
};

But actually I won't work and causes error like this.

/Users/.../project_root/node_modules/loopback/lib/models/access-token.js:201
    id = req.param(params[i]);
             ^
TypeError: Object #<IncomingMessage> has no method 'param'
    at tokenIdForRequest (/Users/ksuzuki/Projects/appsocially/repo/chat-center/node_modules/loopback/lib/models/access-token.js:201:14)
    at Function.AccessToken.findForRequest (/Users/ksuzuki/Projects/appsocially/repo/chat-center/node_modules/loopback/lib/models/access-token.js:123:12)
    at /Users/ksuzuki/Projects/appsocially/repo/chat-center/node_modules/loopback/lib/middleware/token.js:53:16
    at Array.0 (/Users/ksuzuki/Projects/appsocially/repo/chat-center/server/socket.js:15:28)
    at run (/Users/ksuzuki/Projects/appsocially/repo/chat-center/node_modules/socket.io/lib/namespace.js:114:11)
    at Namespace.run (/Users/ksuzuki/Projects/appsocially/repo/chat-center/node_modules/socket.io/lib/namespace.js:126:3)
    at Namespace.add (/Users/ksuzuki/Projects/appsocially/repo/chat-center/node_modules/socket.io/lib/namespace.js:155:8)
    at Client.connect (/Users/ksuzuki/Projects/appsocially/repo/chat-center/node_modules/socket.io/lib/client.js:67:20)
    at Server.onconnection (/Users/ksuzuki/Projects/appsocially/repo/chat-center/node_modules/socket.io/lib/index.js:309:10)
    at Server.EventEmitter.emit (events.js:95:17)

I guess this is because I pass the wrong object type to loopback.token() method.

like image 375
Imad Alazani Avatar asked Nov 10 '22 02:11

Imad Alazani


1 Answers

Well I believe Loopback token is built to be used with express request object. In the latest version(2.x) you could use it if you override AccessToken.findForRequest and implement it you yourself.

But there's another approach to this which is covered in the official documentation:

Basically it suggest using socketio-auth(Which "provides hooks to implement authentication in socket.io without using querystrings to send credentials, which is not a good security practice") and using AccessToken model directly.

I put the code here with a little bit of simplification:

On server-side:

app.io = require('socket.io')(app.start());
require('socketio-auth')(app.io, {
  authenticate: function (socket, value, callback) {

      var AccessToken = app.models.AccessToken;
      //get credentials sent by the client
      var token = AccessToken.count({
        userId: value.userId,
        id: value.id,
      }, callback);  
    }
});

On client-side:

socket.on('connect', function() {
    // You should have retrieved tokenId/userId by calling user.login and
    // saving it in cookies or localStorage.
    socket.emit('authentication', {id: tokenId, userId: userId });
});
like image 185
Farid Nouri Neshat Avatar answered Nov 14 '22 21:11

Farid Nouri Neshat