bixi
Version:
企业级中后台前端解决方案
80 lines (70 loc) • 3.04 kB
text/typescript
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);
}
}
()
export abstract class BaseInterceptor implements HttpInterceptor {
constructor(() 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);
}
}