簡體   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