javascript 在 angularjs 应用程序中注销后,如何禁止用户通过浏览器后退按钮访问上一页?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28854745/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 09:39:00  来源:igfitidea点击:

How to disable users from accessing previous page by browser back button after logout in angularjs application?

javascriptangularjsangularjs-authentication

提问by pratham gn

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.

我有一个 angularjs Web 应用程序。我试图不允许用户在注销后使用浏览器后退按钮转到上一页。我希望向用户显示“请登录以继续”之类的消息。我无法得到任何想法。请建议。

采纳答案by SiriK

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");
                        }
                    })
                })

回答by Gopinath Shiva

You can disable access to previous page using 2 ways:

您可以使用 2 种方式禁用对上一页的访问:

  1. use $stateChangeStart, this method invoke whenever the state is changed, look for token, if token is not found, redirect user to login.
  2. use resolve: resolve will get call before routing happens for the respective state, so inside resolve
  1. 使用$stateChangeStart,每当状态改变时调用此方法,查找令牌,如果未找到令牌,则重定向用户登录。
  2. use resolve:resolve 将在路由发生之前调用相应状态,因此在 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 
  }
})

回答by Raphael Müller

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:

在为 ui.router 定义状态的地方,您可以添加用户定义的数据。例如:

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;
}]);

回答by RegisteredUser

In this mdn article there's explained how to manipulate the browser history:

在这篇 mdn 文章中,解释了如何操作浏览器历史记录:

https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history#Adding_and_modifying_history_entries

https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history#Adding_and_modifying_history_entries

On one of my older projects I used this to create a "to previous page" button.

在我的一个旧项目中,我用它来创建一个“到上一页”按钮。

回答by Markiv

A combination of prevent default and window.history.forward() solved the problem.

结合 prevent default 和 window.history.forward() 解决了这个问题。

$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.

这个想法是 event.preventDefault() 删除历史堆栈。因此,如果我们从 page1 -> page2 -> page3 开始,则 preventDefault 仅在到达主页时才起作用。forward() 需要保持重定向到同一页面。

回答by Viorel Mateianu

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;
            }
        }
    }
);

回答by RicardoGonzales

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.

假设当用户登录到您的应用程序时,系统会生成一个 auth-token,其中包含表明用户已通过身份验证的数据。因此,由于它是在页面渲染上执行的任何控制器,因此您只需要为您的 auth-token 进行一些验证。如果此令牌不存在,则重定向到登录页面。我认为,您不需要阻止任何后退按钮。

// First lines inside your controller.
if (!$tokenManager.getToken()) { // Get token.
    $location.path('/login');
}

The flow would be:

流程是:

  1. The user go to login.html and put its credentials (user/password)
  2. The system validates the credentials and generate an auth-token
  3. The system save the token with lets say: tokenManager.save();
  4. The user is now in welcome.html page.
  5. The user logout from the system.
  6. The system delete the auth-token, let's say: tokenManager.clean();
  7. The user press the back button browser button.
  8. The system try to enter to welcome.html page but it's own controller has the validation.
  9. The user is redirected to login.html
  1. 用户转到 login.html 并输入其凭据(用户/密码)
  2. 系统验证凭据并生成身份验证令牌
  3. 系统保存令牌,可以说: tokenManager.save();
  4. 用户现在位于welcome.html 页面。
  5. 用户从系统注销。
  6. 系统删除auth-token,比方说:tokenManager.clean();
  7. 用户按下后退按钮浏览器按钮。
  8. 系统尝试进入welcome.html 页面,但它自己的控制器有验证。
  9. 用户被重定向到 login.html