Reputation: 397
In a MEAN app, I have an authService module with an Auth factory which contains an authFactory.isLoggedIn function:
// check if a user is logged in
// checks if there is a local token
authFactory.isLoggedIn = function() {
if (AuthToken.getToken())
return true;
else
return false;
};
So I thought I could use this with the resolve property of $routeProvider like this:
var MyModule = angular.module('app.routes', ['ngRoute']);
MyModule.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$routeProvider
// route for the home page
.when('/', {
templateUrl : 'app/views/pages/home.html'
})
// login page
.when('/login', {
templateUrl : 'app/views/pages/login.html',
controller : 'mainController',
controllerAs: 'login'
})
// register page
.when('/register', {
templateUrl: 'app/views/pages/register.html',
controller: 'userCreateController',
controllerAs: 'register'
})
// upload page
.when('/upload', {
templateUrl : 'app/views/pages/upload.html',
controller: 'uploadController',
controllerAs: 'userupload',
resolve: function($q, $location) {
var deferred = $q.defer();
deferred.resolve();
if (!Auth.isLoggedIn) {
$location.path('/login');
}
return deferred.promise;
}
})
//logout
.otherwise({redirectTo: '/'});
$locationProvider.html5Mode(true);
}]);
Unfortunately this doesn't work to stop unauthenticated users accessing the upload page and I don't see any errors being reported. I have seen instances of simpler ways to do this eg:
.when('/upload', {
templateUrl : 'app/views/pages/upload.html',
controller: 'uploadController',
controllerAs: 'userupload',
isLoggedIn: true
})
But that doesn't work either, which is a shame as it's far simpler.
Upvotes: 2
Views: 4421
Reputation: 397
In the end I was determined to use the resolve property of $routeProvider so after experimenting with the solution on http://midgetontoes.com/blog/2014/08/31/angularjs-check-user-login I came up with:
var MyModule = angular.module('app.routes', ['ngRoute']);
MyModule.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
var onlyLoggedIn = function($location, $q, Auth) {
var deferred = $q.defer();
if (Auth.isLoggedIn()) {
deferred.resolve();
} else {
deferred.reject();
$location.url('/login');
}
return deferred.promise;
};
$routeProvider
// route for the home page
.when('/', {
templateUrl : 'app/views/pages/home.html'
})
// login page
.when('/login', {
templateUrl : 'app/views/pages/login.html',
controller : 'mainController',
controllerAs: 'login'
})
// register page
.when('/register', {
templateUrl: 'app/views/pages/register.html',
controller: 'userCreateController',
controllerAs: 'register'
})
// upload page
.when('/upload', {
templateUrl : 'app/views/pages/upload.html',
controller: 'uploadController',
controllerAs: 'userupload',
resolve:{loggedIn:onlyLoggedIn}
})
//logout
.otherwise({redirectTo: '/'});
$locationProvider.html5Mode(true);
}]);
I am sure this isn't as good as the custom http interceptor as posited by @Dimitiri Algazin or as simple as the solution from @Pasan Ratnayake but it does fulfil my quest to use resolve. Thanks to @Dimitri and @Pasan anyway.
Upvotes: 1
Reputation: 495
There are multiple ways you could achieve this functionality.
Easiest would be to add a check similar to below code to each controller that you don't want your users to access.
// You could re-direct the user to a '401' state as well
if (!authFactory.isLoggedIn())
$state.go('login');
Upvotes: 0
Reputation: 3456
Add custom http interceptor. This is not exact code, just algorithm, some syntax might missing:
.factory('myHttpInterceptor', function($q, $location, AuthToken) {
function isLoggedIn() {
return !!AuthToken.getToken();
}
function canRecover(response) {
var status = response.status;
var config = response.config;
var method = config.method;
var url = config.url;
console.log("--->>> ", method, status, url);
if (status == 401) {
alert("401");
} else if ( status == 403) {
alert("403");
} else if (status == 404) {
alert("404");
} else if (status == 405) {
alert("405");
} else if (status == 500) {
alert("500");
} else {
}
return response;
}
return {
// optional method
'request': function(config) {
if (isLoggedIn()) {
return config;
} else {
$location.path('login');
}
},
// optional method
'response': function(response) {
// do something on success
return response;
},
// optional method
'requestError': function(rejection) {
return $q.reject(canRecover(rejection));
},
// optional method
'responseError': function(rejection) {
return $q.reject(canRecover(rejection));
}
};
})
.config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push('myHttpInterceptor');
}])
Upvotes: 0