ohayolibs
Version:
Ohayo is a set of essential modules for ohayojp.
93 lines (83 loc) • 3.52 kB
text/typescript
import {
HttpErrorResponse,
HttpEvent,
HttpHandler,
HttpInterceptor,
HttpParams,
HttpRequest,
HTTP_INTERCEPTORS,
} from '@angular/common/http';
import { Injectable, Injector, Optional } from '@angular/core';
import { OhayoAuthConfig, OhayoConfigService } from '@ohayo/util';
import { Observable, Observer } from 'rxjs';
import { mergeConfig } from '../auth.config';
import { ToLogin } from './helper';
import { ITokenModel } from './interface';
class HttpAuthInterceptorHandler implements HttpHandler {
constructor(private next: HttpHandler, private interceptor: HttpInterceptor) { }
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: OhayoAuthConfig): boolean;
abstract setReq(req: HttpRequest<any>, options: OhayoAuthConfig): HttpRequest<any>;
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const options = mergeConfig(this.injector.get(OhayoConfigService));
if (Array.isArray(options.ignores)) {
for (const item of options.ignores) {
if (item.test(req.url)) return next.handle(req);
}
}
const ingoreKey = options.allow_anonymous_key!;
let ingored = false;
let params = req.params;
let url = req.url;
if (req.params.has(ingoreKey)) {
params = req.params.delete(ingoreKey);
ingored = true;
}
const urlArr = req.url.split('?');
if (urlArr.length > 1) {
const queryStringParams = new HttpParams({ fromString: urlArr[1] });
if (queryStringParams.has(ingoreKey)) {
const queryString = queryStringParams.delete(ingoreKey).toString();
url = queryString.length > 0 ? `${urlArr[0]}?${queryString}` : urlArr[0];
ingored = true;
}
}
if (ingored) {
return next.handle(req.clone({ params, url }));
}
if (this.isAuth(options)) {
req = this.setReq(req, options);
} else {
ToLogin(options, this.injector);
// Interrupt Http request, so need to generate a new Observable
const err$ = new Observable((observer: Observer<HttpEvent<any>>) => {
const res = new HttpErrorResponse({
url: req.url,
headers: req.headers,
status: 401,
statusText: `来自 @ohayo/auth 的拦截,所请求URL未授权,若是登录API可加入 [url?_allow_anonymous=true] 来表示忽略校验,更多方法请参考: https://ohayojp.com/auth/getting-started#OhayoAuthConfig\nThe interception from @ohayo/auth, the requested URL is not authorized. If the login API can add [url?_allow_anonymous=true] to ignore the check, please refer to: https://ohayojp.com/auth/getting-started#OhayoAuthConfig`,
});
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), {
handle: (_: HttpRequest<any>) => err$,
});
return chain.handle(req);
}
}
return err$;
}
return next.handle(req);
}
}