希望有人可以指导我解决这个问题。
编码Angular 6应用程序时,我正在使用Custom-Reuse-Strategy来缓存用户访问过的页面,并使用HttpInterceptor来处理401/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'); } } }