Skip to content

Commit 4a6755e

Browse files
authoredAug 26, 2022
feat: add ALLOW_ANONYMOUS, CUSTOM_ERROR, IGNORE_BASE_URL, RAW_BODY (#1486)
1 parent 6df7c38 commit 4a6755e

12 files changed

+133
-5
lines changed
 

‎packages/auth/docs/getting-started.en-US.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ The default `DelonAuthModule` does not register any HTTP interceptor, because of
7777
| `[token_send_place]` | `header,body,url` | `header` | Send token parameter position ||
7878
| `[login_url]` | `string` | `/login` | Login page routing address ||
7979
| `[ignores]` | `RegExp[]` | `[ /\/login/, /assets\// ]` | Ignore the list of URL addresses ||
80-
| `[allow_anonymous_key]` | `string` | `_allow_anonymous` | Anonymous login KEY identification, if the request parameter with the KEY is to ignore token check and add action, the key value will be removed when the request is truth ||
80+
| (deprecated) `[allow_anonymous_key]` | `string` | `_allow_anonymous` | Will be removed in 15.0.0, Pls used [ALLOW_ANONYMOUS](https://github.com/ng-alain/delon/blob/master/packages/auth/src/token.ts) `HttpContext` instead. Anonymous login KEY identification, if the request parameter with the KEY is to ignore token check and add action, the key value will be removed when the request is truth ||
8181
| `[executeOtherInterceptors]` | `boolean` | `true` | Whether continue to call other interceptor `intercept` method after token missing ||
8282
| `[refreshTime]` | `number` | `3000` | Refresh time (unit: ms) ||
8383
| `[refreshOffset]` | `number` | `6000` | Offset value (unit: ms), it is recommended to set according to the multiple of `refreshTime` ||

‎packages/auth/docs/getting-started.zh-CN.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ export class AppModule { }
7777
| `[token_send_place]` | `header,body,url` | `header` | 发送token参数位置 ||
7878
| `[login_url]` | `string` | `/login` | 登录页路由地址 ||
7979
| `[ignores]` | `RegExp[]` | `[ /\/login/, /assets\// ]` | 忽略 URL 地址清单 ||
80-
| `[allow_anonymous_key]` | `string` | `_allow_anonymous` | 允许匿名登录标识号,若请求参数中带有该KEY表示忽略TOKEN校验与添加动作,同时真实请求时会移除该数据 ||
80+
| (deprecated) `[allow_anonymous_key]` | `string` | `_allow_anonymous` | Will be removed in 15.0.0, Pls used [ALLOW_ANONYMOUS](https://github.com/ng-alain/delon/blob/master/packages/auth/src/token.ts) `HttpContext` instead. 允许匿名登录标识号,若请求参数中带有该KEY表示忽略TOKEN校验与添加动作,同时真实请求时会移除该数据 ||
8181
| `[executeOtherInterceptors]` | `boolean` | `true` | 是否校验失效时命中后继续调用后续拦截器的 `intercept` 方法 ||
8282
| `[refreshTime]` | `number` | `3000` | 刷新时长(单位:ms) ||
8383
| `[refreshOffset]` | `number` | `6000` | 偏移值(单位:ms),建议根据 `refreshTime` 倍数来设置 ||

‎packages/auth/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@ export * from './src/token/jwt/jwt.guard';
1414
export * from './src/token/simple/simple.model';
1515
export * from './src/token/simple/simple.interceptor';
1616
export * from './src/token/simple/simple.guard';
17+
export * from './src/token';
1718
export * from './src/auth.config';
1819
export * from './src/auth.module';

‎packages/auth/src/token.ts

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { HttpContextToken } from '@angular/common/http';
2+
3+
/**
4+
* Whether to allow anonymous login
5+
*
6+
* 是否允许匿名登录
7+
*
8+
* @example
9+
* this.http.post(`login`, {
10+
* name: 'cipchk', pwd: '123456'
11+
* }, {
12+
* context: new HttpContext().set(ALLOW_ANONYMOUS, true)
13+
* })
14+
*/
15+
export const ALLOW_ANONYMOUS = new HttpContextToken(() => false);

‎packages/auth/src/token/base.interceptor.spec.ts

+10
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { DOCUMENT } from '@angular/common';
33
import {
44
HttpClient,
5+
HttpContext,
56
HttpEvent,
67
HttpHandler,
78
HttpInterceptor,
@@ -19,6 +20,7 @@ import { Observable, throwError, catchError } from 'rxjs';
1920
import { AlainAuthConfig, ALAIN_CONFIG } from '@delon/util/config';
2021

2122
import { DelonAuthModule } from '../auth.module';
23+
import { ALLOW_ANONYMOUS } from '../token';
2224
import { AuthReferrer, DA_SERVICE_TOKEN, ITokenModel, ITokenService } from './interface';
2325
import { SimpleInterceptor } from './simple/simple.interceptor';
2426
import { SimpleTokenModel } from './simple/simple.model';
@@ -126,6 +128,14 @@ describe('auth: base.interceptor', () => {
126128
});
127129
});
128130

131+
it('#ALLOW_ANONYMOUS', () => {
132+
genModule({}, genModel(SimpleTokenModel, null));
133+
http.get('/user', { context: new HttpContext().set(ALLOW_ANONYMOUS, true) }).subscribe();
134+
const ret = httpBed.expectOne(() => true);
135+
expect(ret.request.headers.get('Authorization')).toBeNull();
136+
ret.flush('ok!');
137+
});
138+
129139
describe('#with allow_anonymous_key', () => {
130140
describe('in params', () => {
131141
it(`should working`, done => {

‎packages/auth/src/token/base.interceptor.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { Observable, Observer } from 'rxjs';
1414
import { AlainAuthConfig, AlainConfigService } from '@delon/util/config';
1515

1616
import { mergeConfig } from '../auth.config';
17+
import { ALLOW_ANONYMOUS } from '../token';
1718
import { ToLogin } from './helper';
1819
import { ITokenModel } from './interface';
1920

@@ -36,6 +37,8 @@ export abstract class BaseInterceptor implements HttpInterceptor {
3637
abstract setReq(req: HttpRequest<any>, options: AlainAuthConfig): HttpRequest<any>;
3738

3839
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
40+
if (req.context.get(ALLOW_ANONYMOUS)) return next.handle(req);
41+
3942
const options = mergeConfig(this.injector.get(AlainConfigService));
4043
if (Array.isArray(options.ignores)) {
4144
for (const item of options.ignores) {
@@ -70,11 +73,15 @@ export abstract class BaseInterceptor implements HttpInterceptor {
7073
ToLogin(options, this.injector);
7174
// Interrupt Http request, so need to generate a new Observable
7275
const err$ = new Observable((observer: Observer<HttpEvent<any>>) => {
76+
let statusText = '';
77+
if (typeof ngDevMode === 'undefined' || ngDevMode) {
78+
statusText = `来自 @delon/auth 的拦截,所请求URL未授权,若是登录API可加入 [url?_allow_anonymous=true] 来表示忽略校验,更多方法请参考: https://ng-alain.com/auth/getting-started#AlainAuthConfig\nThe interception from @delon/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://ng-alain.com/auth/getting-started#AlainAuthConfig`;
79+
}
7380
const res = new HttpErrorResponse({
7481
url: req.url,
7582
headers: req.headers,
7683
status: 401,
77-
statusText: `来自 @delon/auth 的拦截,所请求URL未授权,若是登录API可加入 [url?_allow_anonymous=true] 来表示忽略校验,更多方法请参考: https://ng-alain.com/auth/getting-started#AlainAuthConfig\nThe interception from @delon/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://ng-alain.com/auth/getting-started#AlainAuthConfig`
84+
statusText
7885
});
7986
observer.error(res);
8087
});

‎packages/theme/public_api.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ export * from './src/services/i18n/index';
1010
export * from './src/locale/index';
1111
export * from './src/services/modal/modal.helper';
1212
export * from './src/services/drawer/drawer.helper';
13-
export * from './src/services/http/http.client';
14-
export * from './src/services/http/http.decorator';
13+
export * from './src/services/http/index';
1514
export * from './src/pipes/date/date.pipe';
1615
export * from './src/pipes/keys/keys.pipe';
1716
export * from './src/pipes/yn/yn.pipe';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { HttpContextToken } from '@angular/common/http';
2+
3+
/**
4+
* Whether to customize the handling of exception messages
5+
*
6+
* 是否自定义处理异常消息
7+
*
8+
* @example
9+
* this.http.post(`login`, {
10+
* name: 'cipchk', pwd: '123456'
11+
* }, {
12+
* context: new HttpContext()
13+
* .set(ALLOW_ANONYMOUS, true)
14+
* .set(CUSTOM_ERROR, true)
15+
* }).subscribe({
16+
* next: console.log,
17+
* error: console.log
18+
* });
19+
*/
20+
export const CUSTOM_ERROR = new HttpContextToken(() => false);
21+
22+
/**
23+
* Whether to ignore API prefixes
24+
*
25+
* 是否忽略API前缀
26+
*
27+
* @example
28+
* // When environment.api.baseUrl set '/api'
29+
*
30+
* this.http.get(`/path`) // Request Url: /api/path
31+
* this.http.get(`/path`, { context: new HttpContext().set(IGNORE_BASE_URL, true) }) // Request Url: /path
32+
*/
33+
export const IGNORE_BASE_URL = new HttpContextToken(() => false);

‎packages/theme/src/services/http/index.en-US.md

+28
Original file line numberDiff line numberDiff line change
@@ -153,3 +153,31 @@ class RestService extends BaseApi {
153153
- `@Payload` Request Payload
154154
- Supported body (like`POST`, `PUT`) as a body data, equivalent to `@Body`
155155
- Not supported body (like `GET`, `DELETE` etc) as a `QueryString`
156+
157+
### CUSTOM_ERROR
158+
159+
Whether to customize the handling of exception messages.
160+
161+
```ts
162+
this.http.post(`login`, {
163+
name: 'cipchk', pwd: '123456'
164+
}, {
165+
context: new HttpContext()
166+
.set(ALLOW_ANONYMOUS, true)
167+
.set(CUSTOM_ERROR, true)
168+
}).subscribe({
169+
next: console.log,
170+
error: console.log
171+
});
172+
```
173+
174+
### IGNORE_BASE_URL
175+
176+
Whether to ignore API prefixes.
177+
178+
```ts
179+
// When environment.api.baseUrl set '/api'
180+
181+
this.http.get(`/path`) // Request Url: /api/path
182+
this.http.get(`/path`, { context: new HttpContext().set(IGNORE_BASE_URL, true) }) // Request Url: /path
183+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export * from './http.client';
2+
export * from './http.decorator';
3+
export * from './http.token';

‎packages/theme/src/services/http/index.zh-CN.md

+30
Original file line numberDiff line numberDiff line change
@@ -153,3 +153,33 @@ class RestService extends BaseApi {
153153
- `@Payload` 请求负载
154154
- 当支持 Body 时(例如:`POST``PUT`)为内容体等同 `@Body`
155155
- 当不支持 Body 时(例如:`GET``DELETE` 等)为 `QueryString`
156+
157+
## HttpContext
158+
159+
### CUSTOM_ERROR
160+
161+
是否自定义处理异常消息。
162+
163+
```ts
164+
this.http.post(`login`, {
165+
name: 'cipchk', pwd: '123456'
166+
}, {
167+
context: new HttpContext()
168+
.set(ALLOW_ANONYMOUS, true)
169+
.set(CUSTOM_ERROR, true)
170+
}).subscribe({
171+
next: console.log,
172+
error: console.log
173+
});
174+
```
175+
176+
### IGNORE_BASE_URL
177+
178+
是否忽略API前缀。
179+
180+
```ts
181+
// When environment.api.baseUrl set '/api'
182+
183+
this.http.get(`/path`) // Request Url: /api/path
184+
this.http.get(`/path`, { context: new HttpContext().set(IGNORE_BASE_URL, true) }) // Request Url: /path
185+
```

‎packages/util/config/auth/auth.type.ts

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ export interface AlainAuthConfig {
3737
ignores?: RegExp[];
3838
/**
3939
* 允许匿名登录KEY,若请求参数中带有该KEY表示忽略TOKEN,默认:`_allow_anonymous`
40+
*
41+
* @deprecated Will be removed in 15.x, Pls used [ALLOW_ANONYMOUS](https://github.com/ng-alain/delon/blob/master/packages/auth/src/token.ts) `HttpContext` instead
4042
*/
4143
allow_anonymous_key?: string;
4244
/**

0 commit comments

Comments
 (0)
Please sign in to comment.