Angular 2 AuthGuard + Firebase身份验证 [英] Angular 2 AuthGuard + Firebase Auth

查看:190
本文介绍了Angular 2 AuthGuard + Firebase身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



这是AuthGuard服务:

  import'Injectable} from'@ angular / core'; 
从'@ angular / router'导入{CanActivate,Router,
ActivatedRouteSnapshot,
RouterStateSnapshot};
从'./auth.service'导入{AuthService};
$ b @Injectable()
导出类AuthGuard实现了CanActivate {

构造函数(private AuthService:AuthService,
private router:Router){}

canActivate(route:ActivatedRouteSnapshot,state:RouterStateSnapshot){
if(this.AuthService.loggedIn){return true; }

this.router.navigate(['login']);
返回false;






$ b

这是AuthService,它检查用户的日志并将结果绑定到其构造函数中的loggedIn属性。

pre $ import $ {@ angular / core' ;
从'angularfire2'导入{AngularFire};
从'@ angular / router'导入{Router};

@Injectable()
export class AuthService {
loggedIn:boolean = false;

构造函数(
public af:AngularFire,
public router:Router){
af.auth.subscribe(user => {
if(用户){
this.loggedIn = true;
}
});






$ b

这里的问题显然是不同步的。 AuthGuard的canActivate()总是返回一个错误的值,因为订阅没有及时收到数据来将'loggedIn'改为true。



解决这个问题的最佳实践是什么?

编辑:

更改AuthGuard返回一个observable。

  canActivate(route:ActivatedRouteSnapshot,state:RouterStateSnapshot){
return this.af.auth.map((auth)=> {
if(!auth){
this.router.navigateByUrl('login');
return false;
}
return true;
});



$ b $ p
$ b $ p

这样的工作,因为你没有得到重定向登录...但目标AuthGuarded组件不呈现。



不知道它是否与我的app.routes。这是该部分的代码:

  const routes:Routes = [
{path:'',component: MainComponent,canActivate:[AuthGuard]},
...
];

export const routing = RouterModule.forRoot(routes);使用.take(1)来完成可观察事物(1)以使得组件呈现。

  import {Observable} fromrxjs / Observable; 
导入'rxjs / add / operator / map';
导入'rxjs / add / operator / take';
$ b canActivate(route:ActivatedRouteSnapshot,state:RouterStateSnapshot){
return this.af.auth.map((auth)=> {
if(!auth){
this.router.navigateByUrl('login');
return false;
}
return true;
})。take(1);
}


I'm trying to build an AuthGuard for Angular 2 routes using Firebase Auth.

This is the AuthGuard Service:

import { Injectable }             from '@angular/core';
import { CanActivate, Router,
         ActivatedRouteSnapshot,
         RouterStateSnapshot }    from '@angular/router';
import { AuthService }            from './auth.service';

@Injectable()
export class AuthGuard implements CanActivate {

  constructor(private AuthService: AuthService, 
                private router: Router) {}

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    if (this.AuthService.loggedIn) { return true; }

    this.router.navigate(['login']);
    return false;
  }
}

And this is the AuthService which checks if the user's logged in and binds the result to the property 'loggedIn' in its constructor.

import { Injectable } from '@angular/core';
import { AngularFire } from 'angularfire2';
import { Router } from '@angular/router';

@Injectable()
export class AuthService {
loggedIn: boolean = false;

  constructor(
    public af: AngularFire,
    public router: Router) {
        af.auth.subscribe(user => {
            if(user){
                this.loggedIn = true;
            }
        });
    }
}

The problem here is obviously asynchrony. AuthGuard's canActivate() always returns a false value because the subscription doesn't receive the data in time to change 'loggedIn' to true.

What's the best practice to fix this?

EDIT:

Changed the AuthGuard to return an observable.

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    return this.af.auth.map((auth) => {
        if (!auth) {
          this.router.navigateByUrl('login');
          return false;
        }
        return true;
    });
  }

It kind of works since you don't get redirected to login... But the target AuthGuarded Component is not rendered.

Not sure if it has to do with my app.routes. This is the code for that part:

const routes: Routes = [
  { path: '', component: MainComponent, canActivate: [AuthGuard] },
  ...
];

export const routing = RouterModule.forRoot(routes);

解决方案

Complete the observable using .take(1) to make the component render.

import {Observable} from "rxjs/Observable";
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/take';

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    return this.af.auth.map((auth) => {
        if (!auth) {
          this.router.navigateByUrl('login');
          return false;
        }
        return true;
    }).take(1);
  }

这篇关于Angular 2 AuthGuard + Firebase身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆