如何防止Angular 6自定义重用策略缓存403禁止页面?

时间:2018-11-20 18:18:00

标签: angular caching angular6 angular-http-interceptors

希望有人可以指导我解决这个问题。

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

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

  1. 用户点击并说一个链接,该链接转到/ blogs
  2. 向我的dotnet webapi控制器发出了http请求,该控制器检查用户角色,例如“作者”。控制器将该用户标识为不具有“作者”角色,因此它将返回403(禁止的)状态代码。
  3. 拦截器组件获取此403状态并将用户重定向到“禁止”页面。

这一切都很好,但是

即使拦截器在403上启动并进行重定向,重用策略组件仍将/ blogs页面缓存到其缓存页面数组中。因此,当用户单击链接再次进入/ blogs路由时,缓存将启动并向用户提供页面,由于这次没有从重用缓存中提取http请求,因此没有发出http请求,因此403被禁止没有在拦截器中接收,因此向用户显示了一个呈现一半的/ blogs页面(由于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');
            }
        }
    }

0 个答案:

没有答案