techpines / express.io

Realtime Micro Framework for Nodejs
express-io.org
1.59k stars 235 forks source link

How would I require authorization for a route? #93

Open zacharynevin opened 10 years ago

zacharynevin commented 10 years ago

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
    }
})
Lesterpig commented 10 years ago

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/

zacharynevin commented 10 years ago

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) {
     }
})
Lesterpig commented 10 years ago

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

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 !

zacharynevin commented 10 years ago

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
})
Lesterpig commented 10 years ago

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

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