Angular 2 - 路由保护不能处理浏览器刷新

时间:2017-03-08 16:55:12

标签: angular angular2-routing

在app.module.ts中定义这些路线

...
{ path: 'mypath', component: MyComponent, canActivate: [RouteGuard] }, 
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: '**', redirectTo: '/home'}

和这个警卫服务

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

@Injectable()

export class RouteGuard implements CanActivate {

  private loggedIn: boolean;

  constructor ( private af: AngularFire, private auth: AngularFireAuth ) {}

  canActivate(): boolean {

    this.auth.subscribe(auth => {
      if  (auth)  { this.loggedIn = true; }
      else        { this.loggedIn = false; }
//          this.router.navigate(['/login']); for future implememtation
       });

    return this.loggedIn;
  }
}
  

从应用转到的网址//mysite/mypath刷新浏览器   //mysite代替//mysite/mypath(并且还会跳过默认值   路线)。

在mypath路线上没有激活任何守卫(即:{ path: 'mypath', component: MyComponent }一切正常。

有人知道这是一个Angular bug吗? 我怎么能避免这种行为?

我的开发环境是:

@angular/cli: 1.0.0-rc.1
node: 7.5.0
os: linux x64
@angular/cli: 1.0.0-rc.1
@angular/common: 2.4.9
@angular/compiler: 2.4.9
@angular/compiler-cli: 2.4.9
@angular/core: 2.4.9
@angular/flex-layout: 2.0.0-rc.1
@angular/forms: 2.4.9
@angular/http: 2.4.9
@angular/material: 2.0.0-beta.2
@angular/platform-browser: 2.4.9
@angular/platform-browser-dynamic: 2.4.9
@angular/router: 3.4.9

感谢您的帮助。

PS:我试图在Stack Overflow或Github问题上找到答案而没有找到答案。我看到了一个类似的问题Angular 2 routing not working on page refresh with Apache,但这不是我的情况。

3 个答案:

答案 0 :(得分:2)

你可以向路线警卫发送异步结果:

 canActivate(): Promise<boolean> {
   let self = this;
    return this.auth.toPromise().then(auth => {
         if  (auth)  { self.loggedIn = true; }
         else { self.loggedIn = false; }

         self.router.navigate(['/login']); for future implememtation

        return self.loggedIn;
    });


}

答案 1 :(得分:2)

感谢@Bougarfaoui El houcineYounesM的建议,这是我的新警卫服务(完全取自这篇文章:Create a Full Angular Authentication System with Firebase

  

它完美无缺,解决了我的问题。

import { CanActivate, Router } from '@angular/router';
import { AngularFireAuth } from "angularfire2/angularfire2";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs/Rx";
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/take';

@Injectable()
export class RouteGuard implements CanActivate {

    constructor(private auth: AngularFireAuth, private router: Router) {}

    canActivate(): Observable<boolean> {
      return Observable.from(this.auth)
        .take(1)
        .map(state => !!state)
        .do(authenticated => {
      if 
        (!authenticated) this.router.navigate([ '/login' ]);
      })
    }

}

答案 2 :(得分:1)

您正在对您的身份验证服务进行异步调用,这意味着canActivate()会在之前返回this.loggedIn ,并将其值设置为true或false。因为每当你采取“我的路径”时都会打电话给警卫。 route this.isLoggedin将重置为null

现在要避免这种行为,您可以使用警卫的布尔外部,并使用该布尔来跟踪您是否已登录。