本篇文章给大家谈谈angularjs–我应该如何确保用户访问后端呈现的前端路由已经过身份验证?,同时本文还将给你拓展angular2检查用户是否经过身份验证、AngularJSUI路由器登录身份验证、
本篇文章给大家谈谈angularjs – 我应该如何确保用户访问后端呈现的前端路由已经过身份验证?,同时本文还将给你拓展angular2检查用户是否经过身份验证、AngularJS UI路由器登录身份验证、angularjs – angular ui-router登录身份验证、angularjs – Angular中的JWT身份验证 – 多个身份验证级别等相关知识,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:- angularjs – 我应该如何确保用户访问后端呈现的前端路由已经过身份验证?
- angular2检查用户是否经过身份验证
- AngularJS UI路由器登录身份验证
- angularjs – angular ui-router登录身份验证
- angularjs – Angular中的JWT身份验证 – 多个身份验证级别
angularjs – 我应该如何确保用户访问后端呈现的前端路由已经过身份验证?
在前端,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,我强烈希望使用某种基于令牌的身份验证.
解决方法
我认为有几个教程可供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检查用户是否经过身份验证
我从我的服务器获取一个令牌,并希望将其存储在本地存储中(除非有人更好地在应用程序中保留令牌).我遇到的主要问题是,当令牌发生变化时,我无法检测到组件中的变化.
通过阅读大约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函数.似乎代码运行一次,但之后不再运行.我认为问题更多的是潜在的观察者/订阅关系,尽管……
如果您已经阅读了整篇文章,我向您表示祝贺,并深深感谢您花时间阅读本文,这是迄今为止我最长的帖子.如果我能提供更多信息以帮助提出如何解决此问题的想法,请告诉我.
解决方法
当用户登录时,我将令牌保存在本地存储中并在我的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的新手,在以下情况下我对如何使用angular-“ ui-router”感到有些困惑:
我正在构建一个包含两个部分的Web应用程序。第一部分是带有登录和注册视图的主页,第二部分是仪表板(成功登录后)。
我index.html
为home部分创建了一个带有角度应用程序和ui-
router
配置的,用于处理/login
和/signup
查看,还有一个dashboard.html
针对仪表板部分的文件,其应用程序和ui-
router
配置用于处理许多子视图。
现在,我完成了仪表板部分,并且不知道如何将这两个部分与不同的角度应用程序结合在一起。我如何告诉家用应用程序重定向到仪表板应用程序?
angularjs – angular ui-router登录身份验证
我建立一个由两个部分组成的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身份验证 – 多个身份验证级别
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值放入用户模型中.但那又怎样?添加此功能和维护现有身份验证的完整性的最佳方法是什么(我担心安全性)?
我从未使用过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身份验证 – 多个身份验证级别的相关知识,请在本站进行查询。
本文标签: