繁体   English   中英

使用打字稿向 AWS Elasticsearch Service 发出签名请求

[英]Making signed requests to AWS Elasticsearch Service with typescript

我需要的是使用 typescript lambda 将流数据从 DynamoDB 加载到 Amazon Elasticsearch Service。

流数据按预期到达,但我无法弄清楚如何使用签名对 HTTP 请求进行身份验证。 AWS 似乎有一些私有 API 用于签署和发出此 JS 代码中引用的 HTTP 请求(用于将数据从 S3 加载到 ES):

/*
 * Add the given document to the ES domain.
 * If all records are successfully added, indicate success to lambda
 * (using the "context" parameter).
 */
function postDocumentToES(doc, context) {
    var req = new AWS.HttpRequest(endpoint);

    req.method = 'POST';
    req.path = path.join('/', esDomain.index, esDomain.doctype);
    req.region = esDomain.region;
    req.body = doc;
    req.headers['presigned-expires'] = false;
    req.headers['Host'] = endpoint.host;

    // Sign the request (Sigv4)
    var signer = new AWS.Signers.V4(req, 'es');
    signer.addAuthorization(creds, new Date());

    // Post document to ES
    var send = new AWS.NodeHttpClient();
    send.handleRequest(req, null, function(httpResp) {
        var body = '';
        httpResp.on('data', function (chunk) {
            body += chunk;
        });
        httpResp.on('end', function (chunk) {
            numDocsAdded ++;
            if (numDocsAdded === totLogLines) {
                // Mark lambda success.  If not done so, it will be retried.
                console.log('All ' + numDocsAdded + ' log records added to ES.');
                context.succeed();
            }
        });
    }, function(err) {
        console.log('Error: ' + err);
        console.log(numDocsAdded + 'of ' + totLogLines + ' log records added to ES.');
        context.fail();
    });
}

来源: https : //github.com/aws-samples/amazon-elasticsearch-lambda-samples/blob/master/src/s3_lambda_es.js

但是在用 TS 编写时,我似乎无法导入Signers.V4NodeHttpClient库,我猜是因为它们是“私有 API”。

另一个令人困惑的因素是,在本文档中,我们被告知 aws-sdk 会自动对传出请求进行身份验证,而我们不需要自己进行身份验证: https : //docs.aws.amazon.com/general/latest/gr/ signing_aws_api_requests.html

任何人都可以对如何使用 TypeScript 进行身份验证/签名并将带有 AWS Lambda 凭证的 http 请求发送到 AWS 服务(如 Elasticsearch)有一些见解吗?

这是我对与 Amazon Elasticsearch AWS4 签名请求兼容的 Elasticsearch 客户端的实现:

import { Client } from "@elastic/elasticsearch";
import * as AWS4 from "aws4";
import { Connection } from "@elastic/elasticsearch";
import { ConnectionOptions } from "@elastic/elasticsearch/lib/Connection";
import * as http from "http";
import { Readable } from "stream";

interface RequestOptions extends http.ClientRequestArgs {
    asStream?: boolean;
    body?: string | Buffer | Readable | null;
    querystring?: string;
}

class AwsEsConnection extends Connection {
    constructor(opts?: ConnectionOptions) {
        super(opts);
    }

    getBodyString(body?: string | Buffer | Readable | null): string | null {
        if (!body) {
            return body as null;
        }

        if (typeof body === "string" || body instanceof String) {
            return body as string;
        }

        if (body instanceof Buffer) {
            return body.toString();
        }

        if (body instanceof Readable) {
            throw new Error("Haven't implemented stream handling!!");
        }

        return body;
    }

    public request(
        params: RequestOptions,
        callback: (
            err: Error | null,
            response: http.IncomingMessage | null
        ) => void
    ): http.ClientRequest {
        const body = this.getBodyString(params.body);
        const opts = {
            method: params.method,
            host: params.host,
            path: `${params.path}?${params.querystring}`,
            service: "es",
            region: "eu-west-1",
            body: body,
            headers: params.headers
        };

        AWS4.sign(opts);

        params.headers = opts.headers;
        params.body = opts.body;

        return super.request(params, callback);
    }
}

export class ElasticClientFactory {
    constructor(
        private esClusterBaseUrl: string,
    ) {}

    create(): Client {
        return new Client({
            node: this.esClusterBaseUrl,
            Connection: AwsEsConnection
        });
    }
}

我用这个包也有很好的结果,它在引擎盖下做同样的事情,本质上:

https://www.npmjs.com/package/aws-elasticsearch-connector

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM