Loopback 4 OpenAPI 连接器:为每个请求指定授权 header 值
Loopback 4 OpenAPI connector: Specify Authorization header value per request
我已经按照 here and for unauthorized requests, it is working well; I managed to create the respective datasource, service and controller. My service is similar to the GeocoderProvider example 所述在 Loopback 4 中设置了一个 OpenAPI 连接器,但是,比方说,使用以下服务接口。
export interface MyExternalService {
search_stuff(params: {query?: string}): Promise<MyExternalServiceResponse>;
}
export interface MyExternalServiceResponse {
text: string;
}
在我的控制器中,我这样调用它,其中 this.myExternalService
是注入的服务(有点不相关,但 Loopback 也可以隐式解析来自外部 [=28= 的 JSON 响应] 数据源?):
@get('/search')
async searchStuff(@param.query.string('query') query: string): Promise<void> {
return JSON.parse(
(await this.myExternalService.search_stuff({query})).text,
);
}
现在,对应于 myExternalService.search_stuff
的外部端点需要一个 Authorization: Bearer <token>
header,其中令牌由客户端 发送到 Loopback ,即它不是一个静态的 API 键左右。假设我将 @param.query.string('token') token: string
添加到我的 searchStuff
控制器方法的参数列表中,我如何将该令牌转发到 OpenAPI 连接器?这是底层 OpenAPI YAML 定义文件的相关部分:
paths:
/search:
get:
security:
- Authorization: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/SearchResults'
operationId: search-stuff
components:
securitySchemes:
Authorization:
type: http
scheme: Bearer
我现在使用的是OpenAPI连接器的底层execute
函数,手动拦截请求(传给requestInterceptor
的对象后来被Swagger直接传给了http模块):
return JSON.parse(
(
await this.myExternalService.execute(
'search_stuff',
{query},
{
requestInterceptor: (req: {headers: {Authorization: string}}) => {
req.headers.Authorization = 'Bearer ' + token;
return req;
},
},
)
).text,
);
我还在MyExternalService
接口中添加了如下方法,灵感来自the connector's actual execute
function:
execute(
operationId: string,
parameters: object,
options: object,
): Promise<MyExternalServiceResponse>;
我发现的一些东西:
- Loopback 在内部使用
swagger-client
模块来执行基于 OpenAPI 的请求。
- 特别是 Swagger 的执行函数的
securities
选项需要一个 Security Definitions Object. There are some quirks 并且实际上也将它传递给 Swagger。
- 在内部,Swagger 构建发送出去的最终 HTTP 请求 here in its source code。在那里,提到了
securities
键,但它从未真正用于请求。这意味着在 this.myExternalService.execute
的第三个参数中手动指定它不会改变任何内容。
我还不会接受这个答案,我期待找到更像环回的方法。
我这样配置我的服务,以注入基本身份验证。
import {inject, lifeCycleObserver, LifeCycleObserver} from '@loopback/core';
import {juggler} from '@loopback/repository';
const SwaggerClient = require('swagger-client');
const config = {
name: 'jira',
connector: 'openapi',
spec: 'swagger-v2.json',
validate: false,
httpClient: (request: any) => {
request.headers["Authorization"] = "Basic " + Buffer.from("test:test").toString('base64');
return SwaggerClient.http(request);
},
};
@lifeCycleObserver('datasource')
export class JiraDataSource extends juggler.DataSource
implements LifeCycleObserver {
static dataSourceName = 'jira';
static readonly defaultConfig = config;
constructor(
@inject('datasources.config.jira', {optional: true})
dsConfig: object = config,
) {
super(dsConfig);
}
}
我已经按照 here and for unauthorized requests, it is working well; I managed to create the respective datasource, service and controller. My service is similar to the GeocoderProvider example 所述在 Loopback 4 中设置了一个 OpenAPI 连接器,但是,比方说,使用以下服务接口。
export interface MyExternalService {
search_stuff(params: {query?: string}): Promise<MyExternalServiceResponse>;
}
export interface MyExternalServiceResponse {
text: string;
}
在我的控制器中,我这样调用它,其中 this.myExternalService
是注入的服务(有点不相关,但 Loopback 也可以隐式解析来自外部 [=28= 的 JSON 响应] 数据源?):
@get('/search')
async searchStuff(@param.query.string('query') query: string): Promise<void> {
return JSON.parse(
(await this.myExternalService.search_stuff({query})).text,
);
}
现在,对应于 myExternalService.search_stuff
的外部端点需要一个 Authorization: Bearer <token>
header,其中令牌由客户端 发送到 Loopback ,即它不是一个静态的 API 键左右。假设我将 @param.query.string('token') token: string
添加到我的 searchStuff
控制器方法的参数列表中,我如何将该令牌转发到 OpenAPI 连接器?这是底层 OpenAPI YAML 定义文件的相关部分:
paths:
/search:
get:
security:
- Authorization: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/SearchResults'
operationId: search-stuff
components:
securitySchemes:
Authorization:
type: http
scheme: Bearer
我现在使用的是OpenAPI连接器的底层execute
函数,手动拦截请求(传给requestInterceptor
的对象后来被Swagger直接传给了http模块):
return JSON.parse(
(
await this.myExternalService.execute(
'search_stuff',
{query},
{
requestInterceptor: (req: {headers: {Authorization: string}}) => {
req.headers.Authorization = 'Bearer ' + token;
return req;
},
},
)
).text,
);
我还在MyExternalService
接口中添加了如下方法,灵感来自the connector's actual execute
function:
execute(
operationId: string,
parameters: object,
options: object,
): Promise<MyExternalServiceResponse>;
我发现的一些东西:
- Loopback 在内部使用
swagger-client
模块来执行基于 OpenAPI 的请求。 - 特别是 Swagger 的执行函数的
securities
选项需要一个 Security Definitions Object. There are some quirks 并且实际上也将它传递给 Swagger。 - 在内部,Swagger 构建发送出去的最终 HTTP 请求 here in its source code。在那里,提到了
securities
键,但它从未真正用于请求。这意味着在this.myExternalService.execute
的第三个参数中手动指定它不会改变任何内容。
我还不会接受这个答案,我期待找到更像环回的方法。
我这样配置我的服务,以注入基本身份验证。
import {inject, lifeCycleObserver, LifeCycleObserver} from '@loopback/core';
import {juggler} from '@loopback/repository';
const SwaggerClient = require('swagger-client');
const config = {
name: 'jira',
connector: 'openapi',
spec: 'swagger-v2.json',
validate: false,
httpClient: (request: any) => {
request.headers["Authorization"] = "Basic " + Buffer.from("test:test").toString('base64');
return SwaggerClient.http(request);
},
};
@lifeCycleObserver('datasource')
export class JiraDataSource extends juggler.DataSource
implements LifeCycleObserver {
static dataSourceName = 'jira';
static readonly defaultConfig = config;
constructor(
@inject('datasources.config.jira', {optional: true})
dsConfig: object = config,
) {
super(dsConfig);
}
}