UNPKG

bixi

Version:

企业级中后台前端解决方案

80 lines (70 loc) 3.04 kB
import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HTTP_INTERCEPTORS } from '@angular/common/http'; import { Injectable, Injector, Optional } from '@angular/core'; import { Observable, Observer } from 'rxjs'; import { mergeConfig } from '../auth.config'; import { BixiConfigService } from '../auth.config.service'; import { BixiAuthConfig } from '../config.type'; import { ToLogin } from './helper'; import { ITokenModel } from './interface'; class HttpAuthInterceptorHandler implements HttpHandler { constructor(private next: HttpHandler, private interceptor: HttpInterceptor) { } // tslint:disable-next-line:no-any handle(req: HttpRequest<any>): Observable<HttpEvent<any>> { return this.interceptor.intercept(req, this.next); } } @Injectable() export abstract class BaseInterceptor implements HttpInterceptor { constructor(@Optional() protected injector: Injector) { } protected model: ITokenModel; abstract isAuth(options: BixiAuthConfig): boolean; // tslint:disable-next-line:no-any abstract setReq(req: HttpRequest<any>, options: BixiAuthConfig): HttpRequest<any>; // tslint:disable-next-line:no-any intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { const options = mergeConfig(this.injector.get(BixiConfigService)); if (options.ignores) { for (const item of options.ignores as RegExp[]) { if (item.test(req.url)) return next.handle(req); } } if ( options.allow_anonymous_key && (req.params.has(options.allow_anonymous_key) || new RegExp(`[\?|&]${options.allow_anonymous_key}=[^&]+`).test(req.urlWithParams)) ) { return next.handle(req); } if (this.isAuth(options)) { req = this.setReq(req, options); } else { console.warn('[@bixi/auth](interceptor): Token 不存在或已过期,前往登录页'); ToLogin(options, this.injector); // Interrupt Http request, so need to generate a new Observable // tslint:disable-next-line:no-any const err$ = new Observable((observer: Observer<HttpEvent<any>>) => { const res = new HttpErrorResponse({ url: req.url, headers: req.headers, status: 401, statusText: `来自 @bixi/auth 的拦截,所请求URL未授权,若是登录API可加入 [url?_allow_anonymous=true] 来表示忽略校验` }); observer.error(res); }); if (options.executeOtherInterceptors) { const interceptors = this.injector.get(HTTP_INTERCEPTORS, []); const lastInterceptors = interceptors.slice(interceptors.indexOf(this) + 1); if (lastInterceptors.length > 0) { const chain = lastInterceptors.reduceRight((_next, _interceptor) => new HttpAuthInterceptorHandler(_next, _interceptor), { // tslint:disable-next-line:no-any handle: (_: HttpRequest<any>) => err$ }); return chain.handle(req); } } return err$; } return next.handle(req); } }