javascript - 使用 Passport-local 和 $routeProvider 进行 MEAN Stack 用户身份验证

标签 javascript angularjs express passport.js mean-stack

我正在使用 Passport-local 将用户登录到我的应用程序。我们通过以下函数登录,该函数在我的 angularJS Controller 中调用。

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

任何有关如何从这里继续前进的帮助将不胜感激。

最佳答案

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

收到未经授权的 header 后,您的 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 事件。一旦您通过登录获得了用户,您就可以将详细信息存储在根范围中以供以后访问。

关于javascript - 使用 Passport-local 和 $routeProvider 进行 MEAN Stack 用户身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42915555/

相关文章:

JavaScript var 到 PHP

javascript - 根据 JavaScript 中的键值查找和删除数组中的对象

javascript - AngularJS 访问复杂天气 JSON 中的值

AngularJS 和模块化

javascript - 将 div 设为其内容宽度的 50%

javascript - onchange 日期输入

javascript - 将 angular-bootstrap-calendar 安装到 Ionic App 中时出现问题

node.js - 如何处理多个域?

javascript - 使用 Passport-google-oauth 向 req.user 添加附加数据

node.js - POST 多对多 express 请求