【问题标题】:MEAN Stack user authentication with passport-local and $routeProvider使用本地护照和 $routeProvider 进行 MEAN Stack 用户身份验证
【发布时间】:2017-08-12 10:28:58
【问题描述】:

我正在使用本地护照将用户登录到我的应用程序。我们通过下面的函数登录,该函数在我的 angularJS 控制器中调用。

$http.post('/login', $scope.user).then(function (response){
    if(response.data.success){
        //If successful I console.log the user data and redirect them to the main page.
        console.log(response.data.user);
        $location.path(response.data.redirectTo);
    } else {
        // Handle the error messages passed back by my express routing.
    }
});

这按预期工作,如果我使用正确的详细信息登录,那么它将 console.log 用户,然后将我重定向到新页面。

我的问题是我现在如何做到这一点,以便我的所有其他页面都可以确保用户已登录?我应该对收到的用户数据使用什么? 我正在谈论的页面使用以下 $routeProvider 路由:

app.config(['$routeProvider', function($routeProvider) {
  $routeProvider.when('/login', {
    templateUrl: 'login.html',
    controller: 'loginCtrl'
  });

  $routeProvider.when('/home', {
    templateUrl: 'home.html',
    controller: 'homeCtrl',
    // Something to make sure the user is logged in
  });

}])

我读过的所有教程都要求我通过快速路由来处理这个问题,但这只会导致重定向循环,因为/login 没有通过isAuthenticated 路由中间件。

app.get('*', isAuthenticated, function(req,res){
    res.sendFile("index.html");
});

function isAuthenticated(req,res,next){
    if(req.isAuthenticated()){
        next();
    } else {
        res.redirect('/login');
    }
}

任何关于如何从这里向前推进的帮助将不胜感激。

【问题讨论】:

    标签: javascript angularjs express passport.js mean-stack


    【解决方案1】:

    您的 angularJs 应用需要检测何时需要登录。为此,您需要为从 express 应用程序获得的所有响应编写一个拦截器,如果需要登录,请显示登录页面。在最好的世界里,你的 express 应用程序不应该重定向到 /login,你应该把路由留给你的 angularJs 应用程序;它应该只发送 json 资源或诸如 401 状态代码响应之类的东西,以表明该请求是未经授权的。

    收到未经授权的标头后,您的 angularJs 拦截器将看到需要登录并显示登录页面:

    app.config(function($httpProvider) {
    
        //configure $http to show a login dialog whenever a 401 unauthorized response arrives
        $httpProvider.responseInterceptors.push(
                function($rootScope, $q, $location) {
    
                    return function(promise) {
                        return promise.then(
                                //success -> don't intercept            
                                function(response) {
                                    return response;
                                },
                                //error -> if 401 save the request and broadcast an event
                                        function(response) {
                                    if (response.status === 403 || response.status === 401) {
                                                var deferred = $q.defer(),
                                                        req = {
                                                            path: $location.path(),
                                                            config: response.config,
                                                            deferred: deferred
                                                        };
                                                $rootScope.requests401.push(req);
                                                $rootScope.$broadcast('event:loginRequired');
                                                return deferred.promise;
                                            }
                                            return $q.reject(response);
                                        }
                                );
                            };
                });
             });            
    app.run(function($rootScope, $http, $location, base64) {
    
    
    /**
     * Holds all the requests which failed due to 401 response.
     */
    $rootScope.requests401 = [];
    
    $rootScope.$on('event:loginRequired', function() {
        $location.path('/login');
    });
    
    /**
     * On 'event:loginConfirmed', resend all the 401 requests.
     */
    $rootScope.$on('event:loginConfirmed', function(){
    
        var i, requests = $rootScope.requests401,
                retry = function(req) {
                    $http(req.config).then(function(response) {
                        req.deferred.resolve(response);
                    });
                };
    
            });
    });
    

    在此设置中,您的 LoginCtrl 还需要发出 loginConfirmed 事件。从登录中获得用户后,您可以将详细信息存储在根范围内以供以后访问。

    【讨论】:

      猜你喜欢
      • 2014-11-15
      • 2016-03-06
      • 2017-03-21
      • 1970-01-01
      • 2016-10-02
      • 1970-01-01
      • 2017-06-14
      • 2016-10-19
      • 2016-10-29
      相关资源
      最近更新 更多