首页 > 解决方案 > Angular router.navigate 在 403 错误后无法正常工作

问题描述

简要描述;简介

在我的应用程序中,有 100 门课程,用户只能访问其中的几个。如果他点击其他人,他会得到 403 错误。当他点击受限课程时,从那里所有其他导航都失败(甚至到他有权访问的课程)并且router.navigate 解析为 'false'。那是在点击事件上,router.navigate 不起作用并且只发出 NavigationCancel 。

Angular-7


错误模式

  1. 我有搜索框,我使用材料输入和材料自动完成将课程列为用户类型。
  2. 搜索课程Angular(允许),点击第一个结果,成功导航/Course/499
  3. 搜索 course React (restricted course),点击第一个结果,所以显示 403 error/course/78(403 错误)
  4. 再次搜索Angular,单击第一个结果,但现在不导航

代码

COURSE.COMP.HTML

<form class="search-form" *ngIf="cardsLoaded">
    <mat-form-field appearance="fill">
      <mat-label>Search courses</mat-label>
      <input
        matInput
        placeholder="eg. angular"
        name="search"
        autocomplete="off"
        #searchInput
        [formControl]="searchBox"
        [matAutocomplete]="auto"
      />
      <mat-autocomplete
        #auto="matAutocomplete"
        [displayWith]="displayFn"
        (optionSelected)="loadCourse($event.option.value.id)"  // FUNCTION TO NAVIGATE
      >
        <mat-option *ngIf="flag.searching">Searching Courses...</mat-option>
        <mat-option *ngFor="let course of list" [value]="course">
          <span class="option">
            <span
              class="{{ course.course_status }}"
              [innerHTML]="course.name | highlight: searchInput.value"
            ></span>
            <i> {{ course.course_status }} </i>
          </span>
        </mat-option>
      </mat-autocomplete>
      <mat-icon matSuffix>search</mat-icon>
    </mat-form-field>
  </form>

COURSE.COMP.TS

/**
 * Redirects user to the course page
 * @param id course id
 */
loadCourse(id: number) {
  console.log(`--------------LOADING COURSE (${id})---------------`); // i am getting correct courseId on every click
  this.router.navigate([`/Course/${id}`]).then(nav => {
    console.log('Yayy', nav); // true if navigation is successful
  }, err => {
    console.log('Navigation Failed', err) // when there's an error
    // this returns flase everytime, after clicking on a restricted course.
  });
}

警卫

export class AuthGuard implements CanActivate {
  constructor(
    private router: Router,
    private authService: AuthService,
    private store: Store<State>
  ) {}

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean> {
    return this.authService.getProfile().pipe(
      map(
        // if success return true
        data => {
          this.store.dispatch(new fromCat.StoreProfile(data));
          return true;
        }
      ),
      // if failur return false, and redirect to login page
      catchError(err => {
        this.router.navigate(["/login"]);
        return of(false);
      })
    );
  }
}

令牌拦截器

export class TokenInterceptorService implements HttpInterceptor {
  constructor(
    private authService: AuthService,
    private router: Router,
    private snackbar: MatSnackBar,
    private store: Store<State>
  ) {}

  intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    const token = this.authService.getApi();
    let clonedReq;

    return next.handle(clonedReq).pipe(
      // if api call returns any error, show details in console and redirect to appropriate page
      tap(
        (event: HttpEvent<any>) => {},
        (err: any) => {
          if (err instanceof HttpErrorResponse) {
            ////////// ERROR 404 - REDIRECT //////////
            if (err.status === 404) {
              console.log(
                "%cError in making HTTP request",
                "color: #FF0088; background: #222; font-size: 24px",
                err,
                clonedReq
              );
              this.router.navigate(["/notfound"]);
            }

            ////////// ERROR 403 - SNACKBAR //////////
            if (err.status === 403) {
              console.log('error');
              this.snackbar.open(`You do not have required permissions to perform the action. Please contact admin.`);
            }

            ////////// ERROR 401 - REDIRECT //////////
            if (err.status === 401) {
              this.router.navigate(["/login"]);
            }

            ////////// ERROR 400 - SNACKBAR //////////
            if (err.status === 400) {
              this.snackbar.open(`${err.error.error}`);
            }

            ////////// ERROR 500 - SNACKBAR //////////
            if (err.status === 500) {
              console.log(
                "%cError: 500 \n",
                "color: #FF0088; background: #222; font-size: 24px",
                err
              );
              this.snackbar.open(`${err.status} - ${err.error.error}`);
            }
          }
        }
      )
    );
  }
}


调试


截图

  1. 搜索 id=499 的课程,(可以导航) 导航工作正常
  2. 搜索其他课程(仅限用户,id=78)并点击它。不应按预期导航。 搜索反应
  3. 按预期给出 403 错误。到目前为止还不错 在控制台中给出 403 错误(预期)
  4. 搜索并尝试导航到 course/499。无法导航。 路由器解析为假

请提出可能的解决方案。我不确定为什么路由器会有这样的行为以及如何强制导航它。

标签: angularangular-ui-routerangular-routing

解决方案


推荐阅读