Angular路由守卫-不能正确重定向到登录页面

3
我正在使用一个可激活守卫和一个具有JWT的Node服务器。在正常操作期间,路由工作良好。但是,当令牌过期且页面仍然存在于浏览器中时,我能够在Angular应用程序中单击浏览,尽管没有API数据存在。我多次检查了我的设置,看起来没问题,但出于某种原因,当令牌不存在或已过期时,它没有重定向到登录页面。
----- AUTH GUARD SERVICE
import { Injectable } from "@angular/core";
import { CanActivate } from "@angular/router";
import { AuthService } from "../auth/auth.service";
import { UserService } from "../user.service";

@Injectable({ providedIn: "root" })
export class AuthGuardService implements CanActivate {
  constructor(public userService: UserService, public auth: AuthService) {}

  canActivate(): boolean {
    if (!this.auth.isAuthenticated()) {
      this.userService.logout();
      return false;
    }
    return true;
  }
}

----- 认证服务

import { Injectable } from "@angular/core";
import * as jwt_decode from "jwt-decode";
import { UserService } from "../user.service";
import { Router } from "@angular/router";

@Injectable({ providedIn: "root" })
export class AuthService {
  constructor(public userService: UserService, private _router: Router) {}

  ///// Method to check if user is authenticated (normal employees / non-admin)
  public isAuthenticated(): boolean {
    // Get token from localstorage
    const token = localStorage.getItem("token");

    // Check to see if token exists, if not return false
    if (!token) {
      return false;
    }

    // Decode token and get expiration date
    const decoded = jwt_decode(token);
    const date = decoded.exp;

    // check if expiration is less than current time, if so return true
    if (date < Date.now()) {
      this.userService.setCurrentUser(decoded);
      return true;
    } else {
      return false;
    }
  }
}

----- 基本路由

{
    path: "projects",
    component: ProjectsComponent,
    canActivate: [AuthGuardService]
  },

----- 用户服务退出方法

 // Logout (used in navbar and by auth service)
  logout() {
    localStorage.removeItem(this.TOKEN_KEY);
    this.removeCurrentUser();
    this._router.navigate(["login"]);
  }

所有看起来都是正确的。用户从API获取token并存储到本地。在每个路由上,读取token并检查日期,如果尚未过期,则返回true,路由正常。如果token已过期,则调用用户服务和注销方法。该方法销毁token,删除currentUser属性并将人员导航到登录页面。但登录页面重定向没有发生。
如果我经过一段时间后回到页面并且令牌已过期,则不应该能够在Angular页面之间导航,但出于某种原因我可以。
感谢您提供任何帮助!谢谢!

尝试在登录前添加 /this._router.navigate(["/login"]); - ferhado
我怀疑 token 没有被正确地清除 localStorage。在注销后,在AuthService中放置一个 debuggerconsole.logif(!token) 的内部,确保它被触发。同样,在 AuthGuardService 中,放置一个 console.logdebuggerif(!this.auth.isAuthenticated()) 的内部,并确保在未登录并在页面之间浏览时也被触发。 - AliF50
1个回答

1
使用CanActivate并返回true,允许用户进入路由路径,如果返回false则取消导航。请查看此link
一个类可以实现的接口,用于决定是否可以激活路由。如果所有守卫都返回true,则导航将继续。如果任何守卫返回false,则导航将被取消。如果任何守卫返回UrlTree,则当前导航将被取消,并从守卫返回的UrlTree开始新的导航。
您可能希望注销函数接管这一点,但它可能不像您期望的那样工作。请查看此写作内容以了解如何处理:link
另外,请检查您的代码,可能需要'/',如您的注释中所述。
this._router.navigate(["/login"]);


@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {}

canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
  if (!this.authService.isLoggedIn) {
    // redirect to some view explaining what happened
    this.router.navigateByUrl('/notauthorized');
    return false;
    } else {
      return true;
    }
  }
}

1
谢谢。两个评论都很有帮助。/login 首先提供了帮助,但更重要的是,我开始使用控制台记录日志以查看路由器的位置,并发现它没有触及一些代码。我已将路由和销毁本地存储移入路由器事件中,身份验证仅在服务中进行。 - mike varela

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接