希望有人可以指导我这个问题 .

编写Angular 6应用程序时,我使用Custom-Reuse-Strategy来缓存用户访问过的页面,还使用HttpInterceptor来处理401/403类型的请求 .

我的问题是当这套条件适用时:

  • 用户点击说出去/ blogs的链接

  • http请求发送到我的dotnet webapi控制器,该控制器检查用户角色,例如"Author" . 控制器将此用户标识为没有"Author"角色,因此它返回403(禁止)状态代码 .

  • 拦截器组件获取此403状态并将用户重定向到"forbidden"页面 .

然而,一切正常

即使拦截器正在接收403并进行重定向,重用策略组件仍然将/ blogs页面缓存到它的缓存页面数组中 . 因此,当用户点击链接再次转到/ blogs路由时,缓存启动并向用户提供页面,并且由于从重用缓存中取出,因此此次没有发出http请求,403禁止在拦截器中未被拾取,因此用户被显示为半渲染/博客页面(没有数据,因为webapi没有返回任何数据) .

有没有办法阻止/ blogs页面在处于403禁止状态时被放入重用缓存中?

我试图在重定向到拦截器中的禁止页面之前查看重用缓存,但此时缓存没有/ blogs项 . 它必须在拦截器完成它的工作后添加 .

我知道如果用户没有角色可以隐藏链接但是为了参数,让我们说即使没有正确的角色,链接也是可见的 .

那么,我可以阻止它进入缓存,还是可以基于拦截器以某种方式将其从缓存中删除 .

希望有人可以提供建议 .

谢谢 .

custom-reuse-strategy.ts

import { RouteReuseStrategy, DetachedRouteHandle, ActivatedRouteSnapshot } from "@angular/router";
    import { SignInComponent } from "./user/sign-in/sign-in.component";


    export class CustomReuseStrategy implements RouteReuseStrategy { 

    private handlers: {[key: string]: DetachedRouteHandle} = {};

    private cachedUrls = [
        /home/
      ]

    constructor() {}

    shouldDetach(route: ActivatedRouteSnapshot): boolean {
      return true;
    }

    store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
      let url = route.url.join("/") || route.parent.url.join("/");
      //Don't cache the following urls...
      if(url.startsWith('member/view/') || url.startsWith('post/') || url === "home"){
        return;
      }
      this.handlers[url] = handle; 
    }

    shouldAttach(route: ActivatedRouteSnapshot): boolean {
        let url = route.url.join("/") || route.parent.url.join("/");
        //Logout - remove all cached routes
        if (route.component == SignInComponent) {
          this.handlers = {};
          return false;
        }

        //If this route is cached - load up the cached information
        for (let preservedUrl of this.cachedUrls) {
            if (preservedUrl.test(url)) {
              return false;
            }
        }
        return !!this.handlers[url];    
    }

    retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
      return this.handlers[route.url.join("/") || route.parent.url.join("/")];    
    }

    shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
      return future.routeConfig === curr.routeConfig;
    }


   }

auth.interceptor.ts

import { HttpInterceptor, HttpRequest, HttpHandler, HttpUserEvent, HttpEvent } from "@angular/common/http";
    import { Observable } from "rxjs";
    import { tap } from 'rxjs/operators';
    import { Injectable } from "@angular/core";
    import { Router } from "@angular/router";


    @Injectable()
    export class AuthInterceptor implements HttpInterceptor {

        constructor(private router: Router) { }

        intercept(req: HttpRequest, next: HttpHandler): Observable> {
            if (req.headers.get('No-Auth') == "True")
            {
                return next.handle(req.clone());
            }

            if (localStorage.getItem('userToken') != null) {
                const clonedreq = req.clone({
                    headers: req.headers.set("Authorization", "Bearer " + localStorage.getItem('userToken'))
                });

                return next.handle(clonedreq).pipe
                (
                    tap(
                        succ => { },
                        err => {
                            if (err.status === 401){
                                localStorage.removeItem('userToken');
                                this.router.navigateByUrl('/account/login');
                            }
                            else if (err.status === 403){
                                this.router.navigateByUrl('/forbidden');
                            }
                        }
                    )
                );
            }
            else {
                this.router.navigateByUrl('/account/login');
            }
        }
    }