如何在功能防护中访问 RouterStateSnapshot?(角度15.1.2)

Ced*_*bot 5 angular angular-router angular-guards

我正在编写一个防护程序,可以防止用户在未经身份验证时访问目标网址。我正在编写一个functional guard来实现此目的,但是当我尝试通过界面访问(目标)url 时RouterStateSnapshot,我收到一个空字符串。

在下文中,stackblitz您将发现上述问题的最小重现性。(角度 15.1.2) https://stackblitz.com/edit/angular-ft2rvr

实施functional guard

import { inject } from '@angular/core';
import { Router } from '@angular/router';
import { OAuthService } from 'angular-oauth2-oidc';

export const authGuard = () => {
  const router = inject(Router);
  const oAuthService = inject(OAuthService);
  const hasAccessToken = oAuthService.hasValidAccessToken();
  const hasIdToken = oAuthService.hasValidIdToken();

  console.log('targeUrl', router.routerState.snapshot.url); // router.routerState.snapshot.url returns empty string

  if (!hasAccessToken || !hasIdToken) {
    router.navigate(['authenticate'], {
      state: {
        targetUrl: router.routerState.snapshot.url,
      },
    });
  }
  return hasAccessToken;
};

Run Code Online (Sandbox Code Playgroud)

每当我functional guard用 a替换 时guard service,我就可以通过RouterStateSnapshot. (具体实现见下面的代码块)

import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, CanActivateChild, Router, RouterStateSnapshot } from '@angular/router';
import { OAuthService } from 'angular-oauth2-oidc';

@Injectable({ providedIn: 'root' })
export class AuthGuard implements CanActivate, CanActivateChild {

    constructor(private router: Router, private oAuthService: OAuthService) { }

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        return this.isUserLoggedIn(state.url);
    }

    canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        return this.isUserLoggedIn(state.url);
    }

    private isUserLoggedIn(targetUrl: string): boolean {
        const hasAccessToken = this.oAuthService.hasValidAccessToken();
        if (!hasAccessToken) {
            this.router.navigate(['authenticate'], { state: {
                targetUrl: targetUrl
            }});
        }
        return hasAccessToken;
    }
}
Run Code Online (Sandbox Code Playgroud)

你能告诉我如何访问 a 中的目标 url 吗functional guard

Kar*_*ite 9

尝试更改进入 authGuard 的参数。routerStateSnapshot 应作为参数自动传递。

export const authGuard = (
  route: ActivatedRouteSnapshot,
  state: RouterStateSnapshot,
) => {}
Run Code Online (Sandbox Code Playgroud)