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; }); 我希望这有帮助! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |