Cross domain Sails.js + Socket.io authorization

2019-06-22 09:35发布

I'm working in an application which delivers push content to a group of web applications hosted in different domains. I'm using Sails.js and Socket.io, and structured it like this:

The client script, running on each web application's client's browser, is something like:

socket.on('customEvent', function(message){
    //do something with message on event trigger
}

And then, in the server, the event 'customEvent' is emitted when needed, and it works (e.g. on the onConnect event: sails.io.emit('customEvent',{message ...}).

But I'm facing a problem when it comes to handle authorization. The first approach I've tried is a cookie-based auth, as explained here (by changing the api/config/sockets.js function authorizeAttemptedSocketConnection), but it isn't a proper solution for production and it isn't supported in browsers with a more restrictive cookie policy (due to their default prohibition to third-party cookies).

My question is: how to implement a proper cross-browser and cross-domain authorization mechanism using sails.js, that can be supported in socket.io's authorization process?

======

More details:

  • I also tried adding a login with a well-known oauth provider (e.g. facebook), using this example as a base. I've got the Passport session, but I'm still unable to authenticate from the client script (it only works in pages hosted by my node app directly).
  • A JSONP request to obtain the session might be a solution, but it didn't work well in Safari. Plus I prefer the user to be authenticated in one of the web apps, rather than in my node application directly.

1条回答
Emotional °昔
2楼-- · 2019-06-22 10:21

I believe your routes must handle CORS mate. Example:

'/auth/logout': {
    controller: 'AuthController',
    action: 'logout',
    cors: '*'
},

Of course you can specify the list of ip your are accepting (and then replace the '*').

Worth mentionning that you must specify where socket.io has to connect to (front-end JS):

socket = io.connect(API.url);

For any common http GET/PUT/POST/DELETE, please ensure that your ajax envelope goes with the credentials (cookie). For example with angular:

$httpProvider.defaults.withCredentials = true

Let me know how it goes.

查看更多
登录 后发表回答