Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在已有RESTAPI后端的Angular应用程序中实现登录系统_Javascript_Angularjs_Node.js_Cookies_Login - Fatal编程技术网

Javascript 如何在已有RESTAPI后端的Angular应用程序中实现登录系统

Javascript 如何在已有RESTAPI后端的Angular应用程序中实现登录系统,javascript,angularjs,node.js,cookies,login,Javascript,Angularjs,Node.js,Cookies,Login,我和我的朋友正在开发一个应用程序——我的朋友在后端(Node.js),我在前端 他实现了自己的会话,并为我提供了登录时需要调用的URL。例如,一个POST请求 http://ourapp.heroku.com/login 传递用户名和密码 在我这边,在Angular应用程序中,我创建了一个登录页面,当单击login时,该页面将调用Angular服务。如果此服务从服务器接收到200,它会: $cookieStore.put(cookieNames.LOGGED_IN_COOKIE, true);

我和我的朋友正在开发一个应用程序——我的朋友在后端(Node.js),我在前端

他实现了自己的会话,并为我提供了登录时需要调用的
URL
。例如,一个
POST
请求

http://ourapp.heroku.com/login
传递
用户名
密码

在我这边,在Angular应用程序中,我创建了一个登录页面,当单击
login
时,该页面将调用Angular服务。如果此服务从服务器接收到
200
,它会:

$cookieStore.put(cookieNames.LOGGED_IN_COOKIE, true);
$state.go('home', {}, {reload: true});
问题是,前端的应用程序出现了奇怪的问题。例如,登录和注销通常不起作用。此外,用户即使在注销后也可以进入页面。我发现(至少我认为)我没有正确存储从服务器收到的Cookie,我只是存储了我自己的Cookie


这整件事对我来说仍然很奇怪,因为在PHP或Python应用程序中,你会收到客户端的页面请求,并在发送他请求的页面之前验证他是否登录。在Angular中是不同的-用户已经拥有了所有页面。那么,我如何限制他在不登录的情况下看到的内容,以及如何正确跟踪服务器的cookie?

如果使用ui路由器,您可以执行类似的操作:

首先介绍一些对你所在州的访问级别

$stateProvider
        .state('admin', {
            url: "/admin",
            templateUrl: "/app/views/admin.html",
            controller: "AdminController",
            data: {
                accessLevel: 'admin'
            }
        })
如果您的登录用户具有所需的访问级别,则必须检查状态更改:

您可以创建一个auth服务,该服务实现您的逻辑来登录用户,例如您可以使用该服务

angular.module('app')
   .factory("AuthService", ["$rootScope", "$http", "AuthSession", "AuthHttpBuffer", "AUTH_EVENTS", function ($rootScope, $http, AuthSession, AuthHttpBuffer, AUTH_EVENTS) {

        function loginFailed() {
            $rootScope.$broadcast("auth-change", AUTH_EVENTS.loginFailed);
        };

        AuthSession.load();

        $rootScope.$on('$stateChangeStart', function (event, nextState) {
            if (nextState.data && nextState.data.accessLevel && !service.isAuthorized(nextState.data.accessLevel)) {
                event.preventDefault();
                $rootScope.$broadcast('auth-change', AUTH_EVENTS.loginRequired, nextState.name);
            }
        });

        var service = {
            login: function (credentials) {
                return $http
                            .post('/api/account/login', credentials)
                            .success(function (data, status) {
                                if ((status < 200 || status >= 300) && data.length >= 1) {
                                    loginFailed();
                                    return;
                                }

                                AuthSession.create(data.AccessToken, data.User);
                                $rootScope.$broadcast("auth-change", AUTH_EVENTS.loginSuccess);
                                AuthHttpBuffer.retryAll();
                            }).error(function (data, status) {
                                loginFailed();
                            });
            },
            cancel: function () {
                AuthHttpBuffer.rejectAll();
            },
            logout: function () {
                AuthSession.destroy();
                $rootScope.$broadcast("auth-change", AUTH_EVENTS.logoutSuccess);
            },
            isAuthenticated: function () {
                return (AuthSession.token !== null);
            },
            isAuthorized: function (accessLevel) {
                if (!accessLevel) return true;

                return (this.isAuthenticated() && AuthSession.user.UserRoles.indexOf(accessLevel) !== -1);
            }

        }
        return service;
    }]);
以及常数:

angular.module('app')
      .constant('AUTH_EVENTS', {
        loginSuccess: 'auth-login-success',
        loginFailed: 'auth-login-failed',
        logoutSuccess: 'auth-logout-success',
        loginRequired: 'auth-login-required',
        sessionTimeout: 'auth-session-timeout',
        notAuthorized: 'auth-not-authorized'
      });
如果您希望能够捕获URL,而您没有正确的访问权限,则可以将请求发送到http缓冲区:

angular.module('app')
      .factory('AuthHttpBuffer', ["$injector", function ($injector) {
        /** Holds all the requests, so they can be re-requested in future. */
        var buffer = [];

        /** Service initialized later because of circular dependency problem. */
        var $http;

        function retryHttpRequest(config, deferred) {
            function successCallback(response) {
                deferred.resolve(response);
            }
            function errorCallback(response) {
                deferred.reject(response);
            }
            $http = $http || $injector.get('$http');
            $http(config).then(successCallback, errorCallback);
        }

        return {
            /**
                 * Appends HTTP request configuration object with deferred response attached to buffer.
                 */
            append: function (config, deferred) {
                buffer.push({
                    config: config,
                    deferred: deferred
                });
            },

            /**
                 * Abandon or reject (if reason provided) all the buffered requests.
                 */
            rejectAll: function (reason) {
                if (reason) {
                    for (var i = 0; i < buffer.length; ++i) {
                        buffer[i].deferred.reject(reason);
                    }
                }
                buffer = [];
            },

            /**
                 * Retries all the buffered requests clears the buffer.
                 */
            retryAll: function () {
                for (var i = 0; i < buffer.length; ++i) {
                    retryHttpRequest(buffer[i].config, buffer[i].deferred);
                }
                buffer = [];
            }
        };
      }]);
此拦截器还向所有请求(如果可用)添加会话令牌

要使用此拦截器,必须将以下两行添加到app.config():


您应该查找路由更改事件,以查看用户是否需要登录下一页。。。看起来您正在使用ui路由器进行路由,所以将自定义数据添加到状态定义中,如requiresLogin:true,并在事件块(stateChangeStart)中检查它们。哇,很酷的详细答案!谢谢我将实施我的下一个项目。希望能成功,谢谢。既然我在我的项目中使用了这个,它应该可以工作。(可能我遗漏了太多,因为我在项目中实现了一些附加功能)。请记住,您还应该使用相同/类似的访问权限来保护后端。
angular.module('app')
      .factory('AuthHttpBuffer', ["$injector", function ($injector) {
        /** Holds all the requests, so they can be re-requested in future. */
        var buffer = [];

        /** Service initialized later because of circular dependency problem. */
        var $http;

        function retryHttpRequest(config, deferred) {
            function successCallback(response) {
                deferred.resolve(response);
            }
            function errorCallback(response) {
                deferred.reject(response);
            }
            $http = $http || $injector.get('$http');
            $http(config).then(successCallback, errorCallback);
        }

        return {
            /**
                 * Appends HTTP request configuration object with deferred response attached to buffer.
                 */
            append: function (config, deferred) {
                buffer.push({
                    config: config,
                    deferred: deferred
                });
            },

            /**
                 * Abandon or reject (if reason provided) all the buffered requests.
                 */
            rejectAll: function (reason) {
                if (reason) {
                    for (var i = 0; i < buffer.length; ++i) {
                        buffer[i].deferred.reject(reason);
                    }
                }
                buffer = [];
            },

            /**
                 * Retries all the buffered requests clears the buffer.
                 */
            retryAll: function () {
                for (var i = 0; i < buffer.length; ++i) {
                    retryHttpRequest(buffer[i].config, buffer[i].deferred);
                }
                buffer = [];
            }
        };
      }]);
    angular.module('app')
      .factory('AuthInterceptor', ["$rootScope", "$q", "AuthSession", "AuthHttpBuffer", "AUTH_EVENTS", function ($rootScope, $q, AuthSession, AuthHttpBuffer, AUTH_EVENTS) {

        return {
            request: function (config) {
                config.headers = config.headers || {};
                if (AuthSession.token) {
                    config.headers.Authorization = 'Bearer ' + AuthSession.token.TokenKey;
                }
                return config;
            },
            responseError: function (rejection) {
                if (rejection.status === 401) {
                    var deferred = $q.defer();

                    AuthHttpBuffer.append(rejection.config, deferred);

                    if (AuthSession.token) {
                        $rootScope.$broadcast('auth-change', AUTH_EVENTS.notAuthorized);
                    } else {
                        $rootScope.$broadcast('auth-change', AUTH_EVENTS.loginRequired);
                    }
                    return deferred.promise;
                }
                return $q.reject(rejection);
            }
        }
      }]);
    $httpProvider.defaults.withCredentials = true;
    $httpProvider.interceptors.push("AuthInterceptor");