GVKun编程网logo

angularjs – 我应该如何确保用户访问后端呈现的前端路由已经过身份验证?

2

本篇文章给大家谈谈angularjs–我应该如何确保用户访问后端呈现的前端路由已经过身份验证?,同时本文还将给你拓展angular2检查用户是否经过身份验证、AngularJSUI路由器登录身份验证、

本篇文章给大家谈谈angularjs – 我应该如何确保用户访问后端呈现的前端路由已经过身份验证?,同时本文还将给你拓展angular2检查用户是否经过身份验证、AngularJS UI路由器登录身份验证、angularjs – angular ui-router登录身份验证、angularjs – Angular中的JWT身份验证 – 多个身份验证级别等相关知识,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

angularjs – 我应该如何确保用户访问后端呈现的前端路由已经过身份验证?

angularjs – 我应该如何确保用户访问后端呈现的前端路由已经过身份验证?

我正在使用Laravel和Angular编写一个Web应用程序.

在前端,Laravel用于创建基本模板,但由Angular控制.在后端,laravel用于创建一个宁静的API.

我有几条这样的路线:

Route::group(['domain' => 'domain.com'],function() {

    Route::get('/',['as' => 'home',function () {
        return view('homepage');
    }]);

    Route::get('/login',['as' => 'login',function () {
        return view('login');
    }]);

    //users should be authenticated before accessing this page
    Route::get('/dashboard',['as' => 'dashboard',function () {
        return view('dashboard');
    }]); 

});

Route::group(['domain' => 'api.domain.com','middleware' => ['oauth']],function() {
    Route::post('/post/create',['uses' => 'PostController@store']);
    Route::get('/post/{id}',['uses' => 'PostController@show']);

     //other API endpoints
     // ...
});

我想确保只有经过身份验证的用户才能访问我的domain.com/dashboard网址.

在我的后端,我为我的API路由实现了OAuth,这确保访问这些路由的用户是真实的. OAuth库使用Laravel的Auth :: once()来确保用户凭据正确,然后生成access_token.由于Auth :: once()是一个“无状态”函数,因此不使用会话或cookie,我不能使用Auth :: check()来确保在呈现仪表板页面之前对用户进行身份验证.

我该如何检查用户是否尝试访问domain.com/dashboard?当我将用户从/ login转发到/ dashboard时,我应该在标题中发送access_token吗?或者我应该实现Laravel基于会话/ cookie的身份验证?

编辑:根据这个:Adding http headers to window.location.href in Angular app我无法使用Authorization标头将用户转发到仪表板页面.

为了重用我的移动应用程序的API,我强烈希望使用某种基于令牌的身份验证.

解决方法

我建议使用JWT( JSON Web Tokens)来控制身份验证.

我认为有几个教程可供Lavarel和AngularJS使用.我更喜欢Python并使用Flask,但以下内容看起来很有趣:

> Simple AngularJS Authentication with JWT:AngularJS配置
> Token-Based Authentication for AngularJS and Laravel Apps:与Laravel的联系
> JSON Web Token Tutorial: An Example in Laravel and AngularJS

angular2检查用户是否经过身份验证

angular2检查用户是否经过身份验证

我已经被困在这几天了,需要一些帮助/指导如何检查用户是否在我的angular-rc1应用程序中进行了身份验证.

我从我的服务器获取一个令牌,并希望将其存储在本地存储中(除非有人更好地在应用程序中保留令牌).我遇到的主要问题是,当令牌发生变化时,我无法检测到组件中的变化.

通过阅读大约20个SO帖子/文章,我想我发现最好的方法是在我的user.service.ts中创建一个observable并订阅我的组件中的observable,当用户更改其令牌时我需要检测它.

方法#1 BehaviorSubject – Delegation: EventEmitter or Observable in Angular2

import {BehaviorSubject} from 'rxjs/BehaviorSubject';

export class UserService {
  // Observable userToken source
  _userToken = new BehaviorSubject<string>("");

  // Observable userToken stream
  userToken$= this._userToken.asObservable();

  // set the user token in a way that is observable for subscribed components
  setUserToken(token) {
    this._userToken.next(token);
  }

  ...
}

import {Subscription} from 'rxjs/Subscription';

export class NavBarComponent implements OnInit{
  subscription: Subscription;
  ...

  ngOnInit(){
    this.subscription = this._userService.userToken$.subscribe(
      userToken => {
        console.log('setting user token on navbar to ' + userToken);
        this.userToken = userToken
      });
  }
}

export class LoginComponent implements OnInit {
    ...

    ngOnInit() {
    /*
      Get the authentication code from twitch and then send that authentication
      code to the server. The server does stuff and then either passes back a
      200 with key token in data,or passes back an error 4xxx code.
    */
    var routeParams:any = this._routeParams.params

    if(routeParams.code){
      this.isLoading = true;
      this._userService.authenticateTwitch(routeParams.code)
        .subscribe(resp => {
          this._userService.setUserToken(resp.key);
          this.isLoading = false;
          this._router.navigate(['Search']);
        });
    }
  }
}

好的,所以这个方法的问题是当LoginComponent触发this._userService.setUserToken(resp.key)时,在NavbarComponent中看不到subscribe事件.初始化NavbarComponent时,会触发subscribe方法中的console.log,但是当LoginComponent中的令牌发生更改时,它不会执行任何操作.

方法#1让我感觉很好,我认为这是正确的方法.这只是因为某些原因订阅没有获得更改.

方法#2订阅LocalStorage Change – How can I watch for changes to localStorage in Angular2?(和问题中附带的plunker)

这里我使用“angular2-localstorage”直接使用本地存储:“^ 0.4.0”.我创建一个新服务来处理本地存储更改,然后在我的组件中订阅该Observable

export class StorageService {
  public userToken$: Observable<string>;
  private _userTokenObserver;
  private _userToken;

  constructor() {
    this._userToken = "";
    this.userToken$= new Observable(observer => {
      this._userTokenObserver = observer;
    }).share();
  }

  add(value: string) {
    console.log('setting userToken to ' + value);
    this._userToken = value;
    this._userTokenObserver.next(this._userToken);
  }

  load() {
    this._userTokenObserver.next(this._userToken);
  }
}

    export class NavbarComponent {
        ...

        ngOnInit() {
          console.log('navbar init');
          this._storageService.userToken$.subscribe(latestUserToken => {
            console.log('subscribe fired on navbar with latest user token: ',latestUserToken);
            this.userToken = latestUserToken;
            console.log('user token on nav component is Now: ',this.userToken);
          });

          this._storageService.load();
        }
    }

我的LoginComponent中也有类似的ngOnInit代码.这个方法很有意思,因为subscribe有点在LoginComponent中工作,但在NavbarComponent中却没有.

我说“有点”因为我不认为订阅实际上有效.看起来NavbarComponent首先被初始化并且令牌没有准备好,而LoginComponent在令牌可用之后被初始化.如果令牌发生更改(例如注销并清除令牌),则subscribe方法不会获取更改.

…至少在LoginComponent上!注销在NavbarComponent上,订阅事件在NavbarComponent上触发.因此,事件似乎只包含在发生它的组件中,而不是共享给订阅该事件的所有组件.

navbar init
navbar.component.ts:34 subscribe fired on navbar with latest user token:  
navbar.component.ts:36 user token on nav component is Now: 
login init
user.service.ts:31 authenticating against server with twitch token: aaaaa
storage.service.ts:19 setting userToken to bbbbb
login.component.ts:42 subscribe fired in login componenet with latest usertoken:  bbbbb login.component.ts:44 use

登录组件上的r标记现在是:bbbbbb

其他想法

我认为这些问题的一个可能原因是我的所有组件都是通过RouterOutlet呈现的,而我的NavbarComponent是在app.template.html中直接呈现的.但是,我尝试将导航栏移动到我的组件中,但它仍然具有相同的行为.

<!-- app.template.html -->
<hero-navbar></hero-navbar>
<router-outlet></router-outlet>

另一件事可能是订阅不应该进入ngOnInit函数.似乎代码运行一次,但之后不再运行.我认为问题更多的是潜在的观察者/订阅关系,尽管……

如果您已经阅读了整篇文章,我向您表示祝贺,并深深感谢您花时间阅读本文,这是迄今为止我最长的帖子.如果我能提供更多信息以帮助提出如何解决此问题的想法,请告诉我.

解决方法

我在angular2应用程序上遇到了同样的问题.我通过使用公共ApiService解决了这个问题,该公共ApiService将所需信息添加到请求(即授权标头).调用我的API的其他服务从此服务扩展.

当用户登录时,我将令牌保存在本地存储中并在我的AppState上将属性’isAuthenticated’设置为true.我还将该属性传递给app.component.html中的标题.这样,只要用户登录/注销,您的标头就会自动更新.

app.component.ts:

constructor(public appState: AppState) {
  appState.state.isAuthenticated = false;
}

app.component.html:

<navbar [isAuthenticated]="appState.state.isAuthenticated"></navbar>

navbar.component.ts:

@input() isAuthenticated:boolean;

auth.service.ts:

return this.http.post(this.baseUrl,body,{ headers }).subscribe((result) => {
  localStorage.setItem('oauth',JSON.stringify(result.json()));
  this.appState.set('isAuthenticated',true);

  return result;
});

我希望这有帮助!

AngularJS UI路由器登录身份验证

AngularJS UI路由器登录身份验证

我是AngularJS的新手,在以下情况下我对如何使用angular-“ ui-router”感到有些困惑:

我正在构建一个包含两个部分的Web应用程序。第一部分是带有登录和注册视图的主页,第二部分是仪表板(成功登录后)。

index.html为home部分创建了一个带有角度应用程序和ui- router配置的,用于处理/login/signup查看,还有一个dashboard.html针对仪表板部分的文件,其应用程序和ui- router配置用于处理许多子视图。

现在,我完成了仪表板部分,并且不知道如何将这两个部分与不同的角度应用程序结合在一起。我如何告诉家用应用程序重定向到仪表板应用程序?

angularjs – angular ui-router登录身份验证

angularjs – angular ui-router登录身份验证

我是新的AngularJS,我有点困惑,如何我可以使用angular-“ui路由器”在以下场景:

我建立一个由两个部分组成的Web应用程序。第一部分是具有登录和注册视图的主页,第二部分是仪表板(成功登录后)。

我已经创建了一个index.html的主页部分,其角度应用程序和ui路由器配置来处理/ login和/ signup视图,
还有另一个文件dashboard.html用于仪表板部分及其应用程序和ui-router配置以处理许多子视图。

现在我完成了仪表板部分,不知道如何将这两个部分与他们不同的角度应用程序。如何让家庭应用重定向到信息中心应用?

我正在做一个更好的演示,以及清理一些这些服务成一个可用的模块,但这里是我想出了。这是一个复杂的过程,解决一些注意事项,所以挂在那里。你需要把它分成几部分。

Take a look at this plunk。

首先,您需要一个服务来存储用户的身份。我称之为校长。可以检查用户是否登录,并且根据请求,它可以解析表示关于用户身份的基本信息的对象。这可以是任何你需要的,但必要的将是显示名称,用户名,可能是电子邮件,和用户所属的角色(如果这适用于你的应用程序)。校长还有方法来做角色检查。

.factory('principal',['$q','$http','$timeout',function($q,$http,$timeout) {
    var _identity = undefined,_authenticated = false;

    return {
      isIdentityResolved: function() {
        return angular.isDefined(_identity);
      },isAuthenticated: function() {
        return _authenticated;
      },isInRole: function(role) {
        if (!_authenticated || !_identity.roles) return false;

        return _identity.roles.indexOf(role) != -1;
      },isInAnyRole: function(roles) {
        if (!_authenticated || !_identity.roles) return false;

        for (var i = 0; i < roles.length; i++) {
          if (this.isInRole(roles[i])) return true;
        }

        return false;
      },authenticate: function(identity) {
        _identity = identity;
        _authenticated = identity != null;
      },identity: function(force) {
        var deferred = $q.defer();

        if (force === true) _identity = undefined;

        // check and see if we have retrieved the 
        // identity data from the server. if we have,// reuse it by immediately resolving
        if (angular.isDefined(_identity)) {
          deferred.resolve(_identity);

          return deferred.promise;
        }

        // otherwise,retrieve the identity data from the
        // server,update the identity object,and then 
        // resolve.
        //           $http.get('/svc/account/identity',//                     { ignoreErrors: true })
        //                .success(function(data) {
        //                    _identity = data;
        //                    _authenticated = true;
        //                    deferred.resolve(_identity);
        //                })
        //                .error(function () {
        //                    _identity = null;
        //                    _authenticated = false;
        //                    deferred.resolve(_identity);
        //                });

        // for the sake of the demo,fake the lookup
        // by using a timeout to create a valid
        // fake identity. in reality,you'll want 
        // something more like the $http request
        // commented out above. in this example,we fake 
        // looking up to find the user is
        // not logged in
        var self = this;
        $timeout(function() {
          self.authenticate(null);
          deferred.resolve(_identity);
        },1000);

        return deferred.promise;
      }
    };
  }
])

其次,您需要一个检查用户想要访问的状态的服务,确保他们已登录(如果需要,无需登录,密码重置等),然后进行角色检查(如果您的应用程序需要这个)。如果它们未通过身份验证,请将其发送到登录页面。如果它们已通过身份验证,但未能通过角色检查,请将其发送到访问被拒绝页面。我叫这个服务授权。

.factory('authorization',['$rootScope','$state','principal',function($rootScope,$state,principal) {
    return {
      authorize: function() {
        return principal.identity()
          .then(function() {
            var isAuthenticated = principal.isAuthenticated();

            if ($rootScope.toState.data.roles
                && $rootScope.toState
                             .data.roles.length > 0 
                && !principal.isInAnyRole(
                   $rootScope.toState.data.roles))
            {
              if (isAuthenticated) {
                  // user is signed in but not
                  // authorized for desired state
                  $state.go('accessdenied');
              } else {
                // user is not authenticated. Stow
                // the state they wanted before you
                // send them to the sign-in state,so
                // you can return them when you're done
                $rootScope.returnToState
                    = $rootScope.toState;
                $rootScope.returnToStateParams
                    = $rootScope.toStateParams;

                // Now,send them to the signin state
                // so they can log in
                $state.go('signin');
              }
            }
          });
      }
    };
  }
])

现在所有你需要做的是监听在ui路由器的$stateChangeStart.这让你有机会检查当前状态,他们想去的状态,并插入您的授权检查。如果失败,您可以取消路由转换,或更改到不同的路由。

.run(['$rootScope','$stateParams','authorization',$stateParams,authorization,principal)
{
      $rootScope.$on('$stateChangeStart',function(event,toState,toStateParams)
      {
        // track the state the user wants to go to; 
        // authorization service needs this
        $rootScope.toState = toState;
        $rootScope.toStateParams = toStateParams;
        // if the principal is resolved,do an 
        // authorization check immediately. otherwise,// it'll be done when the state it resolved.
        if (principal.isIdentityResolved()) 
            authorization.authorize();
      });
    }
  ]);

跟踪用户身份的棘手部分是:如果您已经验证(例如,您在上一个会话之后访问该网页,并在Cookie中保存了身份验证令牌,或者您可能已经刷新了某个网页,或者从链接删除到URL)。由于ui路由器的工作方式,您需要在您的身份验证检查之前进行一次身份验证。你可以使用状态配置中的resolve选项。我有一个父状态为所有状态继承的网站,这迫使委托人在任何事情发生之前解决。

$stateProvider.state('site',{
  'abstract': true,resolve: {
    authorize: ['authorization',function(authorization) {
        return authorization.authorize();
      }
    ]
  },template: '<div ui-view />'
})

这里有另一个问题…解决只被调用一次。一旦您的身份查询的承诺完成,它将不再运行解决委托。所以我们必须在两个地方进行你的验证检查:一次根据你的身份承诺解析,这覆盖了你的应用程序第一次加载,一次在$ stateChangeStart如果分辨率已经完成,这涵盖任何时候你导航状态。

好吧,到目前为止我们做了什么?

>我们会检查用户登录时应用加载的时间。
>我们跟踪登录用户的信息。
>我们将其重定向到需要用户登录的状态的登录状态。
>如果他们没有访问权限,我们将它们重定向到访问被拒绝状态。
>我们有一个机制,将用户重定向到他们请求的原始状态,如果我们需要他们登录。
>我们可以签出用户(需要与管理您的身份验证票据的任何客户端或服务器代码一起连接)。
>每当用户重新加载浏览器或关闭链接时,我们不需要将用户重新发送到登录页面。

我们从这里去哪里?那么,您可以将您的状态组织到需要登录的区域中。通过将角色的数据添加到这些状态(或者如果您要使用继承,则可以是这些状态的父级)来请求认证/授权用户。在这里,我们将资源限制为Admins:

.state('restricted',{
    parent: 'site',url: '/restricted',data: {
      roles: ['Admin']
    },views: {
      'content@': {
        templateUrl: 'restricted.html'
      }
    }
  })

现在你可以控制状态,用户可以访问一个路由。任何其他问题?也许只根据视图是否登录才改变视图的一部分?没问题。使用principal.isAuthenticated()或甚至principal.isInRole()与您有条件地显示模板或元素的许多方法中的任何一种。

首先,将principal注入控制器或其他任何东西,并将其粘贴到范围,以便您可以轻松地在您的视图中使用它:

.scope('HomeCtrl',['$scope',function($scope,principal)
{
  $scope.principal = principal;
});

显示或隐藏元素:

<div ng-show="principal.isAuthenticated()">
   I'm logged in
</div>
<div ng-hide="principal.isAuthenticated()">
  I'm not logged in
</div>

等等,等等,等等。无论如何,在您的示例应用程序中,您将有一个主页的状态,将允许未经身份验证的用户删除。它们可以包含指向登录或注册状态的链接,或者将那些表单内置到该页面中。无论适合你。

仪表板页面都可以从需要用户登录的状态继承,也就是说,可以是用户角色成员。我们讨论的所有授权都会从那里流出。

angularjs – Angular中的JWT身份验证 – 多个身份验证级别

angularjs – Angular中的JWT身份验证 – 多个身份验证级别

我正在构建一个带有sails.js后端的角度应用程序.我已将此JWT身份验证合并到应用程序中.
https://github.com/Foxandxss/sails-angular-jwt-example

我仍然在探究身份验证的确切工作方式,我目前正在尝试弄清楚如何添加多个授权级别.
它预先构建为0和1,我想在其上面添加一个管理级别.

它处理现有的授权级别,如下所示:
通过常量为每条路线分配授权级别.因此,所有用户路由都获得在状态中的data属性分配的此访问属性:

$stateProvider
          .state('user',{
            abstract: true,template: '<ui-view/>',data: {
              access: AccessLevels.user
            }
          })

AccessLevels.user是从常量键值对中提取的:

angular.module('app')
  .constant('AccessLevels',{
      anon: 0,user: 1
  });

每当路由导航到时,它都会检查data.access属性以查看该特定路由的访问级别.如果它作为需要身份验证的路由返回,它会检查localStorage是否有令牌.如果有令牌,则路由继续,否则它会引导您.

这是在stateChangeStart上调用的函数:

authorize: function(access) { //<- 'access' will be whatever is in the data property for that state
        if (access === AccessLevels.user) {
          return this.isAuthenticated(); // <- this just grabs the token
        } else {
          return true;
        }
      }

那么添加附加层的最简单方法是什么?
我显然需要将auth_level值放入用户模型中.但那又怎样?添加此功能和维护现有身份验证的完整性的最佳方法是什么(我担心安全性)?

您可以使用 private claims来保存服务器授予的授权.私人声明允许您在JWT中放置您想要的任何其他类型的数据.

我从未使用过node-jsonwebtoken(这似乎是sails.js用于JWT的东西),但看起来你可以直接使用JWT有效负载来访问你期望存在的值,所以你可以做类似的事情.这个:

// Assign authorization on server after successful authentication of an admin
token.auth = AccessLevels.admin;

// Read authorization on client
authorize: function(access) {
    if (access === AccessLevels.anon) {
        return true;
    }
    // Assumes the JWT token is returned by isAuthenticated()
    // (Sorry,not familiar with Sails.js or the JWT example)
    return this.isAuthenticated().auth === access;
}

在身份验证之后,任何后续请求都应该验证用户的授权,可能是通过在您提供的示例中添加类似于“tokenAuth”的添加策略,但是验证提供的JWT上的auth声明与调用任何函数所需的授权相匹配即将被召唤.

今天的关于angularjs – 我应该如何确保用户访问后端呈现的前端路由已经过身份验证?的分享已经结束,谢谢您的关注,如果想了解更多关于angular2检查用户是否经过身份验证、AngularJS UI路由器登录身份验证、angularjs – angular ui-router登录身份验证、angularjs – Angular中的JWT身份验证 – 多个身份验证级别的相关知识,请在本站进行查询。

本文标签: