Sails socket authorization (using passport)

笑着哭i 提交于 2019-12-25 16:51:24

问题


I am using passport for authentication/authorization along with local strategy and a JWT.

Following some research (intensive googling ;) I understand that the best place for the authorization is to use a policy as it applies both for a regular HTTP requests and a socket request (through SailsSocket object that can send 'virtual' HTTP-like requests).

I am now trying to figure out how to use sockets properly and I've seen that there's a beforeConnect handler that allows to reject a connection. While it is not a big deal (as I have a policy that will prevent it from getting data), I want to be able to reject connections - I think its healthier and what reason is there to allow a non-authorized socket connection.

I only want to socket to connect after initial authentication so that in my socket initialization I can set the headers to include the JWT:

io.sails.url = connections.http.baseURL;

io.sails.headers = {
    'Authorization': 'Bearer ' + token
};

io.sails.useCORSRouteToGetCookie = false;

io.socket = io.sails.connect();
io.socket.on('...', someHandler);

This seems to work fine - the socket request hits the JWT policy and I get a req.user in my controller methods for socket requests.

My question is - how do I go about rejecting the user without a token from connecting (and should I even do that?)

When I break inside the beforeConnect I don't see the Authorization header in handshake object.

Update: furthermore, I am now trying to send the token in the query when connecting:

io.socket = io.sails.connect({token: token});

With that, I am able to see the token in the handshake. I'd expect it to be in handshake.query which does not exists. Instead, it is available in handshake._query while the sails docs (here) is claims that is should be under socket.handshake.query (but socket doesn't even exists in beforeConnect and the default function footprint is beforeConnect: function(handshake, cb))

Are these bugs?? Am I missing something?


回答1:


Following discussion with one of the sails developer (here, thanks sgress454):

  1. Headers are not sent with the initial request for connection. It is part of the socket.io specifications and not an issue with sails itself. It maybe possible with newest versions of socket.io to set transportOptions but this isn't integrated into sails yet (2017-04-02).

  2. Any query parameter appears as _query property of the handshake argument. This is not (currently) documented correctly. The documentation will be updated in the near future.

As for the underlying issue - I've implemented the token verification using my own code as I could not find a way to have passport.js integrated in the beforeConnect method. In config/sockets.js I have something like:

beforeConnect: function(handshake, cb) {
    // `true` allows the connection
    // (`false` would reject the connection)

    var token = handshake._query ? handshake._query.token : null;

    CipherService.verifyToken(token, function verifyTokenResults(err, decoded, info) {
        if (err || !decoded) {
            if (err.name === "TokenExpiredError") {
                // token expired - user can't connect...
                return cb(null, false);
            } else {
                // some other error...
                return cb(err, false);
            }
        }

        // here you may want to do other verification, e.g. the user is active
        return cb(null, true);
    });

},

I now have automatic reconnection issues :-( see here )-:



来源:https://stackoverflow.com/questions/42765635/sails-socket-authorization-using-passport

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!