【问题标题】:Why is router.navigate() returning false?为什么 router.navigate() 返回 false?
【发布时间】:2019-07-12 05:52:26
【问题描述】:

我有两个延迟加载模块(站点和 gtd),它们都包含一些路由。我希望 gtd 组件中的所有子路由(带有“app/*”的路径)都受到 AuthGuard 的保护。我正在使用 Auth0 进行身份验证。

但无论出于何种原因,在验证后我尝试调用this.router.navigate('/app'),它总是解析为false。我已经在有和没有AuthGuard 的情况下尝试过它,它会导致相同的行为。所以我不认为这是路由守卫的问题。但以防万一,我已将其包含在此处。

没有错误消息或类似的东西。

为什么路由失败?

这是我的路线:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AuthGuardService as AuthGuard } from './core/auth/auth-guard.service';

const routes: Routes = [
  { path: '', redirectTo: 'site', pathMatch: 'full' },
  { path: 'site', loadChildren: './site/site.module#SiteModule' },
  { path: 'app', loadChildren: './gtd/gtd.module#GtdModule', canActivate: [AuthGuard]},
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

这里是 AuthGuard:

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

@Injectable({
  providedIn: 'root'
})
export class AuthGuardService implements CanActivate {

  constructor(public auth: AuthService, public router: Router) { }

  canActivate(): boolean {
    if (!this.auth.isAuthenticated()) {
      console.log('Not authenticated')
      this.router.navigate(['']);
      return false;
    }
    console.log('Authentication guard satisfied.')
    return true;
  }
}

这是身份验证服务:

import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import * as auth0 from 'auth0-js';
import { LogService } from '../util/log.service';
import { Location } from '@angular/common';
import { environment } from '../../environments/environment';

@Injectable({
  providedIn: 'root'
})
export class AuthService {

  private loginRedirect = environment.auth0.loginRedirectUrl;
  private logoutRedirectTo = environment.auth0.logoutRedirectTo;
  private clientID = environment.auth0.clientID;
  private domain = environment.auth0.domain;

  private _idToken: string;
  private _accessToken: string;
  private _expiresAt: number;

  userProfile: any;

  auth0 = new auth0.WebAuth({
    clientID: this.clientID,
    domain: this.domain,
    responseType: 'token id_token',
    redirectUri: this.loginRedirect,
    scope: 'openid'
  });


  constructor(public router: Router, public logger: LogService, public location: Location) {
    this._idToken = '';
    this._accessToken = '';
    this._expiresAt = 0;
   }

   get accessToken(): string {
     return this.accessToken;
   }

   get idToken(): string {
    return this._idToken;
   }


   public getProfile(cb): void {
     if (!this._accessToken) {
       const errMsg = 'Access Token must exist to fetch profile';
       this.logger.error(errMsg);
       throw new Error(errMsg);
     }

     const self = this;
     this.auth0.client.userInfo(this._accessToken, (err, profile) => {
       if (profile) {
         self.userProfile = profile;
       }

       cb(err, profile);
     });
   }

   login(): void {
     this.auth0.authorize();
   }

   public handleAuthentication(): void {
     this.auth0.parseHash((err, authResult) => {
       if (authResult && authResult.accessToken && authResult.idToken) {
          window.location.hash = '';
          this.localLogin(authResult);
          this.logger.log('Authentication Result:', authResult);
          this.router.navigate(['/app']);
       } else if (err) {
         this.router.navigate(['/home']);
         console.log(err);
       }
     });
   }

   private localLogin(authResult): void {
     // Set isLoggedIn flag in localStorage
     localStorage.setItem('isLoggedIn', 'true');
     // Set the time that the access token will expire at
     const expiresAt = (authResult.expiresAt * 1000) + new Date().getTime();
     this._accessToken = authResult.accessToken;
     this._idToken = authResult.idToken;
     this._expiresAt = expiresAt;
   }


   public renewTokens(): void {
     this.auth0.checkSession({}, (err, authResult) => {
       if (authResult && authResult.accessToken && authResult.idToken) {
         this.localLogin(authResult);
       } else if (err) {
         alert (`Could not get a new token (${err.error}: ${err.error_description}).`);
         this.logout();
       }
     });
   }

   public logout(): void {
     // Remove tokens and expiry time
     this._accessToken = '';
     this._idToken = '';
     this._expiresAt = 0;
     // Remove isLoggedIn flag from localStorage
     localStorage.removeItem('isLoggedIn');

     // Go back to the home route
      window.location.href = `http://${this.domain}/logout?returnTo=${this.logoutRedirectTo}`;

     this.router.navigate(['/']);

     this.logger.info('Access token', this._accessToken);
     this.logger.info('IdToken', this._idToken);
   }

   public isAuthenticated(): boolean {
     // Check whether the current time is past the access token's expiry time
     return new Date().getTime() < this._expiresAt;
   }
}

我在登录回调url中加载的组件中调用handleAuthentication: 从'@angular/core'导入{组件,OnInit}; 从 'src/app/core/auth/auth.service' 导入 { AuthService };

@Component({
  selector: 'app-login-callback',
  templateUrl: './login-callback.component.html',
  styleUrls: ['./login-callback.component.scss']
})
export class LoginCallbackComponent implements OnInit {

  constructor(private authService: AuthService) { }

  ngOnInit() {
    console.log(this.authService.isAuthenticated())
    this.authService.handleAuthentication();
  }

}

我不知道为什么,但this.router.navigate() 解析为false

【问题讨论】:

  • 你试过开启路由追踪吗?这有时有助于了解可能出了什么问题:.forRoot([]) 方法上的`{ enableTracing: true }`。
  • 这很有帮助。我发现导航被取消,因为 navigationTrigger: "hashchange" 是由 window.location.hash = '' 行触发的

标签: angular angular7


【解决方案1】:

你在打电话

this.router.navigate(['app']);

你需要打电话

this.router.navigate(['/app']);

希望这能解决它!

【讨论】:

  • 这是正确的。我会更新我的问题。我应该添加到我已经尝试过它作为相对路径和绝对路径的问题,但它仍然无法导航。
【解决方案2】:

发生的情况是window.location.hash = '' 行触发了另一个导航事件。此事件中断并取消了到 /app 的导航。

甚至不需要清除哈希,因为我立即使用绝对路由进行路由。

【讨论】:

    猜你喜欢
    • 2013-09-18
    • 2014-11-17
    • 2014-03-11
    • 2012-08-24
    • 2013-03-08
    • 2016-09-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多