I have an angularjs web application. I am trying not to allow users to go to previous page using browser back button after logout. I wish to show users a messge like "Please login to continue". I am unable to get any ideas. Please suggest.
-
If you use ui.router, you can add some access related data to your states. and then listen somewhere for the event before state changes. if your user hasn't enough rights to access the resource you can display a login dialog. and after successful login switch the state. you can also add an http interceptor to control api requests and show the login dialog if required. – Raphael Müller Mar 04 '15 at 12:47
-
1How do you handle authentication in your app? Paste in the code that checks if the user is logged in. – Muhammad Reda Mar 04 '15 at 12:49
7 Answers
You can disable access to previous page using 2 ways:
- use
$stateChangeStart
, this method invoke whenever the state is changed, look for token, if token is not found, redirect user to login. use resolve
: resolve will get call before routing happens for the respective state, so inside resolve
Method1:
$rootScope.$on('$stateChangeStart',
function(event, toState, toParams, fromState, fromParams){
// check if user is navigating to anypage other than login, if so check for token, if token is not present redirect to login page
});
Method2:
$stateProvider.state("dashboard", {
resolve: {
// check if user is navigating to anypage other than login, if so check for token, if token is not present redirect to login page by using defer
}
})

- 3,822
- 5
- 25
- 48
You can implement something similar to have access control over different content. Please be aware that you also have to secure your backend.
Where you define your states for the ui.router, you can add user defined data. For example:
angular.module("app", ['ui.router']).config(['$stateProvider', function($stateProvider){
$stateProvider.state('yourSecureState', {
url: '/secure-state',
templateUrl: '/app/views/secure.html',
controller: 'SecureStateController',
data: {
accessLevel: "secured-feature",
title: 'Secured State'
}
});
}]);
With this additional information, you can check in your authentication service if the required access level is available:
angular.module('app').factory('AuthService', ['$rootScope', function($rootScope){
$rootScope.$on('$stateChangeStart', function (event, nextState) {
if (nextState.data && nextState.data.accessLevel && !service.isAuthorized(nextState.data.accessLevel)) {
event.preventDefault();
alert("Not Authorized");
}
});
var service = {
isAuthorized: function(accessLevel) {
//your code here:
}
};
return service;
}]);

- 2,180
- 2
- 15
- 20
In this mdn article there's explained how to manipulate the browser history:
On one of my older projects I used this to create a "to previous page" button.

- 502
- 5
- 10
A combination of prevent default and window.history.forward() solved the problem.
$rootScope.$on('$stateChangeStart',
function(event, toState, toParams, fromState, fromParams){
event.preventDefault();
window.history.forward();
});
The idea is event.preventDefault() removes the history stack. So if we have gone from page1 -> page2 -> page3, the preventDefault works only as long as reaching the home page. forward() is needed to keep redirecting to the same page.

- 479
- 1
- 4
- 14
-
the above code is disabling browser back button , but its not letting me to do signup or forgot pass. i.e even ng-href links are also not working. – Hema Mar 02 '17 at 07:47
The following code disables the browser Back button all over your app:
var allowNav = false;
var checkNav = false;
$rootScope.$on(
'$stateChangeSuccess',
function (event, toState, toStateParams, fromState, fromStateParams) {
allowNav = checkNav;
checkNav = true;
}
);
$rootScope.$on(
'$locationChangeStart',
function (event, next, current) {
// Prevent the browser default action (Going back)
if (checkNav) {
if (!allowNav) {
event.preventDefault();
} else {
allowNav = false;
}
}
}
);

- 4,093
- 1
- 25
- 47

- 11
- 2
app.config(["$routeProvider", function($routeProvider) {
return $routeProvider.when("/", {
redirectTo: "/login"
}).when("/dashboard", {
templateUrl: "views/dashboard.html"
}).when("/login", {
templateUrl: "views/login.html"
}).when("/pages/openAcc", {
templateUrl: "views/pages/openAcc.html"
}).when("/pages/docUpload", {
templateUrl: "views/pages/docUpload.html"
}).when("/pages/listview", {
templateUrl: "views/pages/listview.html"
}).otherwise({
redirectTo: "/404"
})
}]) .run(function($rootScope, $location) {
$rootScope.$on("$routeChangeStart", function (event, next, current) {
if (!(next.templateUrl == "views/login.html")) {
$location.path("/login");
}
})
})

- 30
- 2
-
3Could you please elaborate more your answer adding a little more description about the solution you provide? – abarisone Jun 18 '15 at 06:07
Let's say when the user is logged in to your app, the system generates an auth-token wich contains data that suggest that the user is authenticated. So since any controller it's executed on page render you just need to put a litle validation for your auth-token. If this token is not there, then redirect to login page. I think, you don't need to block any back button.
// First lines inside your controller.
if (!$tokenManager.getToken()) { // Get token.
$location.path('/login');
}
The flow would be:
- The user go to login.html and put its credentials (user/password)
- The system validates the credentials and generate an auth-token
- The system save the token with lets say: tokenManager.save();
- The user is now in welcome.html page.
- The user logout from the system.
- The system delete the auth-token, let's say: tokenManager.clean();
- The user press the back button browser button.
- The system try to enter to welcome.html page but it's own controller has the validation.
- The user is redirected to login.html

- 1,815
- 6
- 32
- 57