Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle authentication in Angular JS application

I am implementing an auth system in my angular js app.

What I am planning it like below:

  1. Get user info(name and pass from login form)
  2. Check whether user exists or not
  3. if exists server respond with a session cookie and frontend will redirect to a certain page.
  4. then user will do some task which will generate API request
  5. API request should have cookie information that was sent on step 3
  6. server check whether the cookie was generated or not and if cookie was found then respond with the API request results. And in my service I am doing something like
    MyApp.service('myAuth', function($http, $q) {
        this.authHeader = null;
        this.checkAuth = function(){
        //do api call and if success sets this.authHeader = response
        }
        this.isAuthenticaed = function(){
            this.authHeader ? return this.authHeder  : return false;
       }

After submitting the login form I will call checkAuth and get my session cookie back from my server, how I can add the cookie information while doing the next REST call and also when user will navigate throughout the application after log in I do want to check each time isAuthenticaed true or false, in Angularjs when it will navigate to another page does it resets after setting it true from the first call? And is my approach 1-6 good or do you have any specific suggestions? Btw I checked previous so entries but those are not what I want to know.

like image 830
arnold Avatar asked Aug 17 '13 11:08

arnold


3 Answers

I am not sure about your backend, but this is how I would do it

  • Create a separate login page (dedicated url not angular sub view or modal dialog).
  • If the user is not authenticated redirect to this login page. This is done by server redirects. This page may or may not use angular framework, as it just involves sending a user\password to server.
  • Make a POST (not AJAX request) from the login page, and verify on server.
  • On the server set the auth cookie. (Different frameworks do it differently. ASP.Net sets form authentication cookie.)
  • Once the user is authenticated redirect user to the actual angular app and load all its components.

This saves any code require to manage authentication on client side in Angular. If the user lands on this page he is authenticated and has the cookie.

Also default browser behavior is to send all cookies associated with a domain with each request, so you don't have to worry if angular is sending some cookie or not.

like image 198
Chandermani Avatar answered Nov 04 '22 16:11

Chandermani


I use the http-auth-interceptor. http://ngmodules.org/modules/http-auth-interceptor

In my backend (asp.net mvc) I build a simple Authentication Service and return an http error 401 if the user is not authenticated. Then I handle the error with a login-view in the SPA site.

like image 39
N0rdl1cht Avatar answered Nov 04 '22 16:11

N0rdl1cht


The ideas put forth by the previous answers will work, but I think they're overkill. You don't need anything this complex.

how I can add the cookie information while doing the next REST call

Turn on withCredentials by default inside $httpProvider like so:

app.config(['$httpProvider', function($httpProvider) {
    $httpProvider.defaults.withCredentials = true;
}]);

Then remove the wildcard (if you had one) from the CORS-related headers, and set allow-credentials, on the server side. In my case, using Python + Flask + Flask-Restful, it's super easy and looks like this:

import Flask
from flask_restful import Api
app = Flask(__name__)
api = Api(app)
api.decorators = [cors.crossdomain(origin='http://localhost:8100', credentials=True)]

Now cookies will be set and returned automatically and transparently by the browser. See these threads for more info:

  • $http response Set-Cookie not accessible
  • Angularjs $http does not seem to understand "Set-Cookie" in the response

when user will navigate throughout the application after log in I do want to check each time isAuthenticaed true or false

As suggested above, have the server return 401 if the auth session expires or is deleted, and use $httpInterceptor in Angular to catch this like so:

app.config(function($httpProvider) {
    var interceptor =
        function($q, $rootScope) {
            return {
                'response': function(response) {
                    return response;
                 },
                'responseError': function(rejection) {
                    if (rejection.status==401) {
                        // Modify this part to suit your needs.
                        // In my case I broadcast a message which is
                        // picked up elsewhere to show the login screen.
                        if (!rejection.config.url.endsWith('/login'))
                        {
                            $rootScope.$broadcast('auth:loginRequired');
                        }
                    }

                    return $q.reject(rejection)
                 }
            }
        };

    $httpProvider.interceptors.push(interceptor);
});
like image 37
Lane Rettig Avatar answered Nov 04 '22 17:11

Lane Rettig