在 Lambda 函数中使用 s3 getObject 生成带有 InvalidToken 错误的 url

Using s3 getObject in Lambda function generates url with InvalidToken error

我正在尝试使用 Lambda 函数中的 getObject 方法为 s3 对象预签名 URL。但是结果 URL 当我在浏览器中打开它时显示 InvalidToken 错误。

我已将 data.txt 文件上传到存储桶。

content.ts

import 'source-map-support/register';
import { APIGatewayProxyHandler } from 'aws-lambda';
import { S3 } from 'aws-sdk';

const s3 = new S3({
    signatureVersion: 'v4'
});

export const getContent: APIGatewayProxyHandler = async (event, context) => {
    const signedUrl = s3.getSignedUrl('getObject', {
        Bucket: process.env.BUCKET,
        Key: 'data.txt',
        Expires: 60
    });

    return {
        statusCode: 200,
        body: JSON.stringify({
            url: signedUrl
        })
    };
}

serverless.yml

service:
  name: purchased-content

custom:
  bucket: "project-paid-content"

plugins:
  - serverless-webpack

provider:
  name: aws
  runtime: nodejs10.x
  region: us-east-2
  iamRoleStatements:
    - Effect: "Allow"
      Action:
       - "s3:GetObject"
      Resource:
        - "arn:aws:s3:::${self:custom.bucket}"
        - "arn:aws:s3:::${self:custom.bucket}/*"

functions:
  getContent:
    handler: content.getContent
    events:
      - http:
          method: get
          path: get
    environment:
      BUCKET: ${self:custom.bucket}

resources:
  Resources:
    PaidContentBucket:
      Type: AWS::S3::Bucket
      Properties:
        BucketName: ${self:custom.bucket}
        AccessControl: Private

您的 IAM 政策似乎没问题。我认为问题可能出在响应上。

return {
        statusCode: 200,
        body: JSON.stringify({
            url: signedUrl
        })
    };

为什么要对返回的 url 进行字符串化。这个应该直接用。 尝试记录返回的 url 并使用它。如果失败,您可能需要进一步查看 IAM policies/roles。