express.io icon indicating copy to clipboard operation
express.io copied to clipboard

How would I require authorization for a route?

Open zacharynevin opened this issue 11 years ago • 5 comments
trafficstars

I have token-based authentication in my app. I have a socket route that does the actual token validation, but I am wondering how I would require some routes be protected by authorization. Let me clarify:

app.io.route('authorize', function(req) {
    AccessToken.validate(req.data.token).then(function(valid) {
        //...stuff
    })
});

// I want these functions to be protected by authorization
app.io.route('needAuthorisation', {
    'example': function(req) {
           //...stuff
    }
})

zacharynevin avatar Jun 19 '14 04:06 zacharynevin

Hi,

You can use socket.get and socket.set functions to save data internally. You can even save datas directly in sockets object if you don't use multi-threading.

For example :

app.io.route('authorize', function(req) {
    AccessToken.validate(req.data.token).then(function(valid) {
        req.socket.set("authorized", true, function() {
           //saved, send notification
        });
    })
});

// I want these functions to be protected by authorization
app.io.route('needAuthorisation', {
    'example': function(req) {
         req.socket.get("authorized", function(authorized) {
             if(!authorized) //not authorized
        });
    }
})

But with socket.io 1.0, these functions are deprecated but correct. Read this for more informations : http://socket.io/docs/migrating-from-0-9/

Lesterpig avatar Jul 08 '14 15:07 Lesterpig

Awesome, thank you! However, I'm really confused with how to translate your example to the middleware pattern for socket.io. The code below illustrates my understanding:

(i.e. there is no understanding)

app.io.route('authorize', function(req) {
    AccessToken.validate(req.data.token).then(function(valid) {
        req.socket.set('authorized', true, function() {
            req.io.emit('authorized!')
        });
    })
})

app.io.route('doesNotNeedAuth', {
    'example1': function(req) {
     }
})

app.io.use(function(socket, next) {
    socket.get('authorized', function(authorized) {
        if (authorized) {
            next()
        } else {
            next('unauthorized')
        }
    })
})

app.io.route('needsAuth', {
    'example2': function(req) {
     }
})

zacharynevin avatar Jul 10 '14 06:07 zacharynevin

The middleware pattern doesn't use set and get. I never used this, but here are some hint to proceed.

  • Use sessions to store data in sockets when authorized (easy with express.io)
  • Use middleware to refuse access to all special routes if not authenticated, with namespaces. Like :
app.io.of("/authorized").use(function(socket, next) {
  if(!socket.session.authorized) 
      next(new Error("not authorized"));
  else next();
});

For now, I think set/get approach is better.

(not tried) good luck !

Lesterpig avatar Jul 10 '14 07:07 Lesterpig

Oh, ok I see. I haven't seen documentation on namespaces with express.io. Does the /authorized namespace correspond to the route in the following way:

app.io.of("/authorized").use(function(socket, next) {
  if(!socket.session.authorized) 
      next(new Error("not authorized"));
  else next();
});

app.route('authorized', {
    // these routes will be authorized
})

zacharynevin avatar Jul 10 '14 20:07 zacharynevin

I suppose, but not sure. Socket.io is not fully documented...

Don't hesitate to try and post your solution :-)

Lesterpig avatar Jul 10 '14 20:07 Lesterpig