Angular JS身份验证维护

时间:2016-12-01 09:10:48

标签: javascript angularjs authentication

我正在寻找最好的建筑解决方案。

我有以下html:

<body ng-controller="individualFootprintController as $ctrl">
<div ng-hide="$ctrl.authenticated">
            <h1>Login</h1>
            With Corporate Account: <a href="/login/corporate">click here</a>
</div>

和控制器:

function individualFootprintController($http) {
        var self = this;
        $http.get("/is_auth").success(function () {
            self.authenticated = true;
        })
            .error(function() {
                self.authenticated = false;
            }
        );
}

问题:

1)此控制器是否适合具有此逻辑?

2)我想拥有实际的“is_authenticated”值。如果我只想发一次请求

,如何才能实现这一点

2 个答案:

答案 0 :(得分:0)

据推测,使用后端进行身份验证需要某种实际的令牌。即您不只是在某处设置true / false标志并将其称为身份验证,但为了能够与后端通信,您需要在请求中包含用户名/密码/ cookie /令牌或请求将被拒绝。

控制器是存放此类东西的不好的地方,因为控制器不是永久性的。或者至少你不应该尽可能使它们永久化。此外,将令牌存储在控制器中不允许任何其他访问它。

  1. 您是否已登录应基于您是否拥有有效的身份验证令牌。
  2. 此令牌必须存储在规范的地方,最适合作为服务。
  3. 其他服务从那里获取令牌,并根据令牌是否可用来决定该应用当前是否“登录”。
  4. 应该如何构建的粗略草图:

    app.service('AuthService', function () {
        this.token = null;
    });
    
    app.service('FooService', function (AuthService, $http) {
        $http.get(..., AuthService.token, ...)
    });
    
    app.controller('LoginStatusController', function (AuthService) {
        Object.defineProperty(this, 'isLoggedIn', {
            get: function () { return AuthService.token != null; }
        });
    });
    
    <div ng-controller="LoginStatusController as ctrl">
        <div ng-hide="ctrl.isLoggedIn">
    

    当您实际登录并获取令牌时,您设置AuthService.token并且它将可供所有其他服务和控制器使用。如果令牌变为无效或未设置,则所有服务和控制器都将失去其身份验证状态。

答案 1 :(得分:0)

我通常做的是以下内容:

使用 ui-router

  • 利用resolve挂钩(解析一些args并将它们注入控制器),并将我的路由定义为主要路由的子路由,检查每次路由更改时的身份验证

    <强>脚本/服务/ user.js的

     angular.module('yourmodule')
      .service('userSrv', function ($http, $q) {
        var srv = {};
    
        srv.getAuthenticatedUser = function() {
          return $http.get("/authenticated_user");
        };
    
        return srv;
      });
    

    <强>脚本/ routes.js

    angular
     .module('yourmodule')
     .config(function ($stateProvider) {
       $stateProvider
        .state('authenticated', {
          abstract: true,
          template: '<ui-view />',
          controller: 'AuthenticatedCtrl',
          resolve: {
            signedInUser: function(userSrv, $q) {
              return userSrv.getAuthenticatedUser()
              .then(function(null, function() {
                //Catch any auth error, likely 403
                //And transform it to null "signedInUser"
                //This is the place to handle error (log, display flash)
                return $q.resolve(null);
              });
            }
          }
        })
        .state('authenticated.myspace', {
          url: '/myspace',
          templateUrl: 'views/myspace.html'
        });
     });
    
  • 利用视图中的$ scope继承

    <强>脚本/控制器/ authenticated.js

     angular.module('yourmodule')
      .controller('AuthenticatedCtrl', function (signedInUser, $scope, $state) {
       //Here you set current user to the scope
       $scope.signedInUser= signedInUser;
    
       $scope.logout = function() {
         //this is where you would put your logout code.
         //$state.go('login');
       };
     });
    

    <强>视图/ myspace.html

     <!-- here you call parent state controller $scope property -->
     <div ng-hide="signedInUser">
       <h1>Login</h1>
         With Corporate Account: <a href="/login/corporate">click here</a>
     </div>
    

1)我想要实际的&#34; is_authenticated&#34;值。如果我只想触发一次请求,怎么能实现这一点 我的解决方案在每次路由更改时要求经过身份验证的用户。这看起来很奇怪,但这实际上是可行且快速的。查询不应该是&gt; 30ms它是引擎盖下的一个非常小的选择。那么,问我&#34;我是否经过身份验证&#34;和#34;获得经过身份验证的用户&#34;是一回事,除了一个返回一个布尔值,另一个返回用户。我建议,就像我告诉你的那样,处理&#34;我是否经过身份验证&#34;通过请求经过身份验证的用户提出问题,然后使用&#34; if(user)&#34; (空值处理)。

2)这个控制器是否适合拥有这个逻辑? 是的,不是。正如您所看到的,控制器是将用户设置为范围事物的地方,但是范围继承允许您不为每个路径重复它。虽然,http api逻辑应移植到服务,并且路由事件(&#34;获取此页面的经过身份验证的用户,请&#34;是路由事件IMHO)应该设置在单独的文件中。

注意:如果您需要完整的路线&#34;保护&#34; (比如在未经过身份验证时重定向,请提出另一个问题,我很乐意回答)