首页 文章

在AngularFire和Angularjs 2中写一个路线守卫等待认证

提问于
浏览
3

我试图在Angular.js 2(2.0.0-rc.4)(由angular cli创建)中编写路由器保护,等待AngularFire(2.0.0-beta.2)检查登录状态并登录用户(匿名)如果用户在允许进入该状态之前已登录 .

我的警卫代码是:

canActivate() {
    /* This part is to detect auth changes and log user in anonymously */
    this.auth
      .subscribe(auth => {
        if (!auth) {
          this.auth.login();
        }
      });

    /* This part is to listen to auth changes and IF there is an auth, resolves this guard with a true to let user in */ 
    return this.auth
      .asObservable()
      .filter(auth => {
        return auth ? true : false;
      })
      .map(x => {
        console.log("TEST 1000");
        return true;
      });
 }

当我运行应用程序时,即使我看到 TEST 1000 控制台输出指示 canActivate() 返回 true 我的路线未激活 .

我想知道我的逻辑中是否存在错误思考,或者是否有任何明智的想法可以智能地调试它 .

2 回答

  • 2

    我正在使用它来检查auth,如果用户是admin:

    认证服务:

    import { Injectable } from '@angular/core';
    
    import { Router } from '@angular/router';
    
    import { AngularFire } from 'angularfire2';
    
    
    import { Observable } from 'rxjs/Observable';
    
    import { Subject } from 'rxjs/Rx';
    
    
    @Injectable()
    
    export class AuthService {
    
    
      admin$: Subject<boolean>;
    
    
      private user: any = null;
    
    
      constructor(private af: AngularFire, private router: Router) {
    
        this.admin$ = <Subject<boolean>>new Subject();
    
        this.af.auth.subscribe(
    
          auth => {
    
            if(auth){
    
              this.user = af.database.object(`users_list/${auth.uid}`).subscribe(
    
                res => {
    
                  this.user = res;
    
                  this.admin$.next(this.user.role === 10);
    
                  this.admin$.complete();
    
                },
    
                err => this.admin$.error(err)
    
              );
    
            }else{
    
              this.router.navigate(['auth']);
    
              this.admin$.next(false);
    
              this.admin$.complete();
    
            }
    
          }
    
        );
    
      }
    
    
      doLogin(credentials){
    
        this.admin$ = <Subject<boolean>>new Subject();
    
        this.af.auth.login(credentials);
    
      }
    
    
      admin() {
    
        return this.admin$;
    
      }
    
    }
    

    Auth Guard服务:

    constructor(private authService: AuthService, private router: Router) { }
    
    
      canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | boolean {
    
    
        this.authService.admin().subscribe(
    
          res => {
    
            // Navigate to the login page
    
            if(!res) {
    
              this.router.navigate(['/auth']);
    
            }
    
          },
    
          err => console.log(err),
    
          () => {
    
            // console.log('auth guard can activate complete')
    
          }
    
        );
    
    
        return this.authService.admin();
    
      }
    

    现在,这与你的问题有什么关系,如果不在 admin$ 上调用 complete() ,它将无效 . 控制台将记录 true 但路由器将不会导航到下一个状态 .

    我几乎仍然得到了observables的悬念(因此执行效果不佳),如果你修复你的代码,我真的很想看到最终的结果,因为它看起来更清洁,可能是一个更好的方法它 . 干杯!

  • 3

    你能测试一下这是否解决了你的问题

    canActivate() {
    
        this.auth
          .subscribe(auth => {
              if (!auth) this.auth.login()
           });
        let authObs = this.auth
          .asObservable()
          .filter(auth => auth ? true : false)
          .map(x => {
              console.log("TEST 1000");
              return true;
           });
    
        authObs.subscribe(a => return true);
    

    我认为问题是你只创建了observable并且实际上并没有订阅它 . CanActivate期望承诺或bool不是可观察的 .

相关问题