繁体   English   中英

您如何计算 PHP 中的 AWS 签名?

[英]How do you calculate an AWS signature in PHP?

我正在 bref 中编写一个 webhook,并希望它向 SQS 发送消息。 为此使用整个 AWS SDK 是一种巨大的浪费。 我如何计算签名?

const AWS_DATETIME_FORMAT = 'Ymd\THis\Z';

$url = getenv('SQS_URL');
$data = [
  'Action' => 'SendMessage',
  'MessageBody' => $body,
  'Expires' => (new DateTime('UTC'))->add(new DateInterval('PT1M'))->format(AWS_DATETIME_FORMAT),
  'Version' => '2012-11-05',
];
$result = Requests::post($url, sign_request($url, $data), $data);

function sign_request($url, $data) {
  // These values are provided by AWS Lambda itself.
  $secret_key = getenv('AWS_SECRET_ACCESS_KEY');
  $access_key = getenv('AWS_ACCESS_KEY_ID');
  $token = getenv('AWS_SESSION_TOKEN');
  $region =  getenv('AWS_REGION');

  $service = 'sqs';

  $current = new DateTime('UTC');
  $current_date_time = $current->format(AWS_DATETIME_FORMAT);
  $current_date = $current->format('Ymd');

  $signed_headers = [
    'content-type' => 'application/x-www-form-urlencoded',
    'host' => "sqs.$region.amazonaws.com",
    'x-amz-date' => $current_date_time,
    'x-amz-security-token' => $token, // leave this one out if you have a IAM created fixed access key - secret pair and do not need the token.
  ];
  $signed_headers_string = implode(';', array_keys($signed_headers));

  $canonical = [
    'POST',
    parse_url($url, PHP_URL_PATH),
    '', // this would be the query string but we do not have one.
  ];
  foreach ($signed_headers as $header => $value) {
    $canonical[] = "$header:$value";
  }
  $canonical[] = ''; // this is always an empty line
  $canonical[] = $signed_headers_string;
  $canonical[] = hash('sha256', http_build_query($data));
  $canonical = implode("\n", $canonical);

  $credential_scope = [$current_date, $region, $service, 'aws4_request'];
  $key = array_reduce($credential_scope, fn ($key, $credential) => hash_hmac('sha256', $credential, $key, TRUE), 'AWS4' . $secret_key);
  $credential_scope = implode('/', $credential_scope);

  $string_to_sign = implode("\n", [
    'AWS4-HMAC-SHA256',
    $current_date_time,
    $credential_scope,
    hash('sha256', $canonical),
  ]);
  $signature = hash_hmac('sha256', $string_to_sign, $key);

  unset($signed_headers['host']);
  $signed_headers['Authorization'] = "AWS4-HMAC-SHA256 Credential=$access_key/$credential_scope, SignedHeaders=$signed_headers_string, Signature=$signature";
  return $signed_headers;
}

请注意,此代码使用rmccue/requests执行 POST 请求。

我的serverless.yml看起来像:

provider:
  name: aws
  region: us-east-1
  runtime: provided.al2
  environment:
    SQS_URL: !Ref BadgeQueue

resources:
  Resources:
    BadgeQueue:
      Type: AWS::SQS::Queue
      Properties:
        RedrivePolicy:
          maxReceiveCount: 3
          deadLetterTargetArn: !GetAtt BadgeDeadLetterQueue.Arn
    BadgeDeadLetterQueue:
      Type: AWS::SQS::Queue
      Properties:
        MessageRetentionPeriod: 1209600

暂无
暂无

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

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