菜单
开源

presign

SignatureV4.presign() 使用 AWS Signature V4 算法预签名 URL。给定 HTTP 请求描述,它返回一个添加了 AWS Signature V4 授权的新 HTTP 请求。它返回一个包含将授权信息编码在其查询字符串中的 url 的对象,可在 k6 HTTP 调用中使用。

参数

presign 方法的第一个参数是一个包含以下属性的对象。

属性类型描述
methodstring请求的 HTTP 方法
endpointEndpoint请求的端点。可以从 aws.js 包以及 signature.js 文件导入 Endpoint 构造函数,它接受 {scheme}://{hostname}[:{port}] 格式的字符串作为输入,允许定义请求的目标(参见下方提供的示例)。
pathstring请求的路径
headersObjectHTTP 请求的头部

您可以提供更多选项并在此特定请求的上下文中覆盖 SignatureV4 选项。为此,将一个包含以下参数的对象作为第二个参数传递给 presign 方法。

属性类型描述
expiresInnumber预签名 URL 过期前的秒数
signingDateDate覆盖签名操作中使用的 Date
signingServicestring在签名操作的上下文中覆盖签名者的 AWS 服务。
signingRegionstring在签名操作的上下文中覆盖签名者的 AWS 区域
unsignableHeadersSet<string>从签名过程中排除头部
signableHeadersSet<string>将头部标记为已签名

返回值

presign 操作返回一个包含以下属性的对象。

属性类型描述
headersObject在 k6 HTTP 请求上下文中使用的预签名请求头部
urlstring在 k6 HTTP 请求上下文中使用的预签名 url

示例

JavaScript
import http from 'k6/http';
import { check } from 'k6';

import {
  AWSConfig,
  Endpoint,
  SignatureV4,
  AMZ_CONTENT_SHA256_HEADER,
  UNSIGNED_PAYLOAD,
} from 'https://jslib.k6.io/aws/0.13.0/signature.js';

const awsConfig = new AWSConfig({
  region: __ENV.AWS_REGION,
  accessKeyId: __ENV.AWS_ACCESS_KEY_ID,
  secretAccessKey: __ENV.AWS_SECRET_ACCESS_KEY,
  sessionToken: __ENV.AWS_SESSION_TOKEN,
});

export default function () {
  // In order to be able to produce pre-signed URLs,
  // we need to instantiate a SignatureV4 object.
  const signer = new SignatureV4({
    service: 's3',
    region: awsConfig.region,
    credentials: {
      accessKeyId: awsConfig.accessKeyId,
      secretAccessKey: awsConfig.secretAccessKey,
      sessionToken: awsConfig.sessionToken,
    },

    /**
     * Whether the URI should be escaped or not.
     */
    uriEscapePath: false,

    /**
     * Whether or not the body's hash should be calculated and included
     * in the request.
     */
    applyChecksum: true,
  });

  // We can now use the signer to produce a pre-signed URL.
  const presignedRequest = signer.presign(
    /**
     * HTTP request description
     */
    {
      /**
       * The HTTP method we will use in the request.
       */
      method: 'GET',

      /**
       * The endpoint of the service we will be making the request to.
       *
       * The endpoint is instantiated from a URL string, of the format: `{scheme}://{hostname}[:{port}]`
       */
      endpoint: new Endpoint('https://s3.us-east-1.amazonaws.com'),

      /**
       * The path of the request.
       */
      path: '/my-bucket/bonjour.txt',

      /**
       * The headers we will be sending in the request.
       *
       * Note that in the specific case of this example, requesting
       * an object from S3, we want to set the `x-amz-content-sha256`
       * header to `UNSIGNED_PAYLOAD`. That way, we bypass the payload
       * hash calculation, and communicate that value instead, as specified.
       */
      headers: { [AMZ_CONTENT_SHA256_HEADER]: 'UNSIGNED-PAYLOAD' },
    },

    /**
     * (optional) pre-sign operation options.
     */
    {
      /**
       * The number of seconds before the pre-signed URL expires
       */
      expiresIn: 86400,

      /**
       * A set of strings whose representing headers that should not be hoisted
       * to pre-signed request's query string. If not supplied, the pre-signer
       * moves all the AWS-specific headers (starting with `x-amz-`) to the request
       * query string. If supplied, these headers remain in the pre-signed request's
       * header.
       * All headers in the provided request will have their names converted to
       * lower case and then checked for existence in the unhoistableHeaders set.
       *
       * In the case of pre-signing S3 URLs, the body needs to be empty.
       * however, the AMZ_CONTENT_SHA256_HEADER needs to be set to
       * UNSIGNED_PAYLOAD. To do this, we need to set the header,
       * but declare it as unhoistable, and unsignable.
       */
      unhoistableHeaders: new Set([AMZ_CONTENT_SHA256_HEADER]),

      /**
       * A set of strings whose members represents headers that cannot be signed.
       * All headers in the provided request will have their names converted to
       * lower case and then checked for existence in the unsignableHeaders set.
       *
       * In the case of pre-signing S3 URLs, the body needs to be empty.
       * however, the AMZ_CONTENT_SHA256_HEADER needs to be set to
       * UNSIGNED_PAYLOAD. To do this, we need to set the header,
       * but declare it as unhoistable, and unsignable.
       */
      unsignableHeaders: new Set([AMZ_CONTENT_SHA256_HEADER]),

      /**
       * A set of strings whose members represents headers that should be signed.
       * Any values passed here will override those provided via unsignableHeaders,
       * allowing them to be signed.
       *
       * All headers in the provided request will have their names converted to
       * lower case before signing.
       */
      signableHeaders: new Set(),

      /**
       * The date and time to be used as signature metadata. This value should be
       * a Date object, a unix (epoch) timestamp, or a string that can be
       * understood by the JavaScript `Date` constructor.If not supplied, the
       * value returned by `new Date()` will be used.
       */
      signingDate: new Date(),

      /**
       * The service signing name. It will override the service name of the signer
       * in current invocation
       */
      signingService: 's3',

      /**
       * The signingRegion and signingService options let the user
       * specify a different region or service to pre-sign the request for.
       */
      signingRegion: 'us-east-1',
    }
  );

  console.log(`presigned URL: ${presignedRequest.url}`);

  /**
   * Our URL is now ready to be used.
   */
  const res = http.get(presignedRequest.url, {
    headers: presignedRequest.headers,
  });

  check(res, { 'status is 200': (r) => r.status === 200 });
}