Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the best design/architecture practice to manage authentication (session) & authorization in a backbone.js application

I couldn't find much on this anywhere. Most of the sample applications just do not talk about security etc. Assume that user will be authenticated using a rest based API call. How the application should be structured to take care of authentication [Also authorization]. A pointer to sample application would be great. Please add views in terms of single page application as well as normal application. [I believe each view should take care of it]

like image 369
Pradeep Kumar Mishra Avatar asked Jun 06 '12 19:06

Pradeep Kumar Mishra


People also ask

Should authentication be a Microservice?

Authentication ensures that only legitimate services and users have access to each microservice. In addition, like in a monolithic app, there is a need to authenticate end-users. When implemented correctly, authentication and authorization are essential assets of a microservices app.


3 Answers

You're absolutely correct that most samples don't address security at all. And as a result I don't have a great sample that I can point you to. I can only tell you how we structured our own stuff:

  1. Like you suggested, we make an API call to authenticate the user. In our case there was a session ID created by the Java server as soon as the user hit the first page (even prior to logging in) and stored in a cookie client side. Since that cookie travels up with every HTTPS request to the server (even the AJAX calls to get data or perform commands) it is associated with a particular account server side once the user has authenticated.

  2. Assuming that your transport to the server is HTTPS and the cookie never travels over the open Internet, nobody can eavesdrop on that value and pretend to be that logged in user.

  3. In our case the server is Java based and a servlet filter sits in front of all of the API functions which are not publicly accessible (that is, the ones that require login). It checks the session and makes sure it represents a logged in user before passing on the request to the service and that keeps the service code clean of authentication checks. Authorization code and parameter validation however does currently sit in the service layer.

  4. AJAX calls to the API could fail to authenticate even when you do have a cookie accompanying them for a variety of reasons (the session has expired, the server had to be restarted and has forgotten the user's session, the admin forceably logged out the user, etc.). In our opinion, it's important that the server still return something (that is, not a empty response) and it shouldn't be something like a redirect to a login page (which is useless to an AJAX request). So we always return JSend protocol responses from all of our functions and if the user isn't logged in, then the servlet filter returns a standard JSend "error" response with a particular code. That allowed us to have our client side code (which you could put into a custom Sync) notice that the user isn't logged in and prompt for a login. It's even possible you could automatically retry the function after they login but that's more sophisticated than we got.

  5. By having the Sync notice that the user isn't logged in or got a security violation you don't have to put anything special into the views. They just make whatever request they think is appropriate and it either succeeds or it doesn't. If a fresh login is needed, that gets triggered at a lower level.

  6. Logging out does not actually require you to kill the local cookie as long as the server marks that given session as no longer logged in or discards the session record.

I disagree somewhat with Derick's statement that the client shouldn't know about security. I think it needs to know when to prompt for login, how to tell the server when to execute a logout, and I always think it's a good idea to have additional checks client side to avoid the principle of surprise. For example, I would prefer that the client suppress showing admin functions to me if I can't use them rather than allow me to try to invoke them and then get an error in response.

Ultimately the server absolutely must check the user's permissions again with each request (because it's so easy to sidestep client-side security), but good UX requires that the client know that I'm not an admin so it can present the best representation of the UI for me.

like image 81
John Munsch Avatar answered Oct 12 '22 17:10

John Munsch


Encountered the same problem a few months back doing a single-page app that consumes a REST based api. What I came up with after searching for answers was to use HTTP's existing 401 and 403 error. I had my api return these errors. Then caught the exceptions by using an extended error handling model to handle these errors and just routed them to my login via the router navigate function.

var ErrorHandlerModel = Backbone.Model.extend({

    initialize: function(attributes, options) {
        options || (options = {});
        this.on("error", this.errorHandler);
        this.init && this.init(attributes, options);
    },

    errorHandler: function(model, error) {
        if (error.status == 401 || error.status == 403) {
          app.history.navigate('login', true);
        }
    }

});

In hindsight though i think it would have been better to just use a global jquery ajaxError function instead. Snippet above was based on a similar question posted here a few months back.

I also had to override backbones default fetch behavior so i could trigger an error with the ogin to catch a response variable included in the json response of the api.

var Login = Backbone.Model.extend({  

    urlRoot: '/login',

    parse: function(resp,xhr) {
        if (resp.response == 'success') {
            app.history.navigate('dashboard', true);
        }
        else {
            this.trigger('loginError');     
        }
    return false;
    }
});
like image 36
Anthony Chua Avatar answered Oct 12 '22 17:10

Anthony Chua


I agree with Mu's comment. There's very little to talk about in terms of authentication.

How do you handle authentication with standard HTML apps that post back to your server? Do it that way because that's how it should be done.

For authorization, there is a little more to talk about, but not much. Essentially, you only send the user what they are allowed to see. You don't do authorization or authentication code in the browser, unless it's absolutely required. And it's never absolutely required in my experience.

JavaScript in a browser is not secure, so don't do things that rely on authentication and authorization in the browser.

I wrote a small article about some of this, here: http://lostechies.com/derickbailey/2012/01/26/modularity-and-security-in-composite-javascript-apps/

like image 41
Derick Bailey Avatar answered Oct 12 '22 15:10

Derick Bailey