Angularjs- Login and Authentication in Each Route and Controller

AngularJS- Login and Authentication in each route and controller

My solution breaks down in 3 parts: the state of the user is stored in a service, in the run method you watch when the route changes and you check if the user is allowed to access the requested page, in your main controller you watch if the state of the user change.

app.run(['$rootScope', '$location', 'Auth', function ($rootScope, $location, Auth) {
$rootScope.$on('$routeChangeStart', function (event) {

if (!Auth.isLoggedIn()) {
console.log('DENY');
event.preventDefault();
$location.path('/login');
}
else {
console.log('ALLOW');
$location.path('/home');
}
});
}]);

You should create a service (I will name it Auth) which will handle the user object and have a method to know if the user is logged or not.

service:

 .factory('Auth', function(){
var user;

return{
setUser : function(aUser){
user = aUser;
},
isLoggedIn : function(){
return(user)? user : false;
}
}
})

From your app.run, you should listen the $routeChangeStart event. When the route will change, it will check if the user is logged (the isLoggedIn method should handle it). It won't load the requested route if the user is not logged and it will redirect the user to the right page (in your case login).

The loginController should be used in your login page to handle login. It should just interract with the Auth service and set the user as logged or not.

loginController:

.controller('loginCtrl', [ '$scope', 'Auth', function ($scope, Auth) {
//submit
$scope.login = function () {
// Ask to the server, do your job and THEN set the user

Auth.setUser(user); //Update the state of the user in the app
};
}])

From your main controller, you could listen if the user state change and react with a redirection.

.controller('mainCtrl', ['$scope', 'Auth', '$location', function ($scope, Auth, $location) {

$scope.$watch(Auth.isLoggedIn, function (value, oldValue) {

if(!value && oldValue) {
console.log("Disconnect");
$location.path('/login');
}

if(value) {
console.log("Connect");
//Do something when the user is connected
}

}, true);

AngularJs route authentication

As @SayusiAndo pointed out you need :

  • http interceptor that will catch the 401 status, from you node server.
  • and, then redirect the user to /login route if not logged in.
  • Also, you should send your jwt token (that you should store), using the same interceptor.

Http interceptor :

app.factory('AuthInterceptor', function ($window, $q) {
return {
request: function(config) {
var token = $window.localStorage.getItem('token');
if(token){
config.headers.Authorization = 'Bearer ' + token;
}

return config;
},
response: function(response) {
if (response.status === 401) {
// redirect to login.
}
return response || $q.when(response);
}
};
});

// Register the AuthInterceptor.
app.config(function ($httpProvider) {
$httpProvider.interceptors.push('AuthInterceptor');
});

Is there any other way to authentication the login page and route

You should include ng-view in html to use different routes

Here I have updated your plunker https://plnkr.co/edit/7L6A6niKMQ4vn2OYP3LN?p=preview

You don't have some files which you are using in routes, I have change your home page for testing please update with yours

How do I check for login or other status before launching a route in Angular with routeProvider?

As in my comments above, there are 3 different paths (plus the ability to use a directive if you want to control it from within html templates). I ended up following

https://midgetontoes.com/angularjs-check-user-login/

which essentially is as follows:

$routeProvider.when('/secure', {
templateUrl: '/secure.html',
controller: 'Secure',
resolve:{
loggedIn:onlyLoggedIn
}
});

And then onlyLoggedIn:

var onlyLoggedIn = function ($location,$q,Auth) {
var deferred = $q.defer();
if (Auth.isLogin()) {
deferred.resolve();
} else {
deferred.reject();
$location.url('/login');
}
return deferred.promise;
};

Simple, works like a charm. If I ever need a directive, I will pull this piece into a service.

AngularJS | handle routing before they load

My solution was combining $locationChangeStart and $routeChangeStart:

$rootScope.$on('$locationChangeStart', function (event) {
//If login data not available, make sure we request for it
if($facebook.isConnected()==null) {
$facebook.getLoginStatus();
event.preventDefault();
return;
}

var next=parseRoute().$$route;
if(!Auth.loginCheck(next))
event.preventDefault();
});

I copied parseRoute() from angular-route.js to parse the given URL to route..

Then I build my login check handler(Auth.loginCheck) in a way that if it fail it return false.

I also use $routeChangeStart to handle $route.reload() events, so now after every change within my authentication status I just do $route.reload():

$rootScope.$on('$routeChangeStart', function (event, next) {
Auth.loginCheck(next);
});

Finally I just make sure that this custom service is always will run by using simple run() method.

Edit:

We now using ngAuth, a module we designed to solve that exact problem(based on the answer I gave here before).

At last, we developed a angular-module that solved this issue.. This module is based on the answer I published here before.

Due the requests here, we published a beta release that works now: http://github.com/GoDisco/ngAuth

Feel free to use it.

Redirect on all routes to login if not authenticated

The best way to do this is to set up a '$routeChangeStart' listener which checks an 'authProvider' service function to verify that there is a user logged in. In our 'app.js' or in a separate file:

angular.module('myApp')
.run(['$rootScope', '$location', 'authProvider', function ($rootScope, $location, authProvider) {
$rootScope.$on('$routeChangeStart', function (event) {

if (!authProvider.isLoggedIn()) {
console.log('DENY : Redirecting to Login');
event.preventDefault();
$location.path('/login');
}
else {
console.log('ALLOW');
}
});
}])

Then for our 'authProvider' service:

angular.module('myApp')
.factory('authProvider', function() {
var user;
return {
setUser : function(aUser){
user = aUser;
},
isLoggedIn : function(){
return(user)? user : false;
}
};
});

This solution was created from an answer here on stack overflow.

Thank you @MohammadAwwaad

AngularJS: Basic example to use authentication in Single Page Application

I like the approach and implemented it on server-side without doing any authentication related thing on front-end

My 'technique' on my latest app is.. the client doesn't care about
Auth. Every single thing in the app requires a login first, so the
server just always serves a login page unless an existing user is
detected in the session. If session.user is found, the server just
sends index.html. Bam :-o

Look for the comment by "Andrew Joslin".

https://groups.google.com/forum/?fromgroups=#!searchin/angular/authentication/angular/POXLTi_JUgg/VwStpoWCPUQJ



Related Topics



Leave a reply



Submit