S3 上传可以在 sls 上离线工作,但在 sls 部署到真实的 aws api url 上后无法工作

问题描述 投票:0回答:1

s3 上传可以在 sls 上离线工作,但在 sls 部署到真实的 aws api url 上后无法工作

在 sls 部署后,我获取端点 url 并尝试上传图像,但它在 s3.putObject 的 catch 块上给出访问被拒绝错误,但在 sls 离线本地上它可以工作,并且在 s3 存储桶中我可以看到文件,但部署后却不能上传和授予访问权限被拒绝。

部署后的真实 Api 与本地主机:

local vs aws  url api - 图片

serverless.yml 如下


org: alvee

app: barikhojo-backend

service: barikhojo-backend

frameworkVersion: '3'

provider:

  name: aws

  region: ap-southeast-1

  runtime: nodejs18.x

  stage: dev

  iam:

    role:

      statements:

      - Effect: Allow

        Action:

        - "s3:*"

        Resource: "arn:aws:s3:::${self:custom.imagesBucketName}" 

      - Effect: Allow

        Action: 

        - 'dynamodb:PutItem'    

        - 'dynamodb:Get*'    

        - 'dynamodb:Scan'    

        - 'dynamodb:Query'    

        - 'dynamodb:UpdateItem'    

        - 'dynamodb:DeleteItem'    

        Resource: "arn:aws:dynamodb:${aws:region}:${aws:accountId}:table/${self:custom.propertyTable}"

  environment: 

    BUCKET_NAME: ${self:custom.imagesBucketName}

    PROPERTY_TABLE: ${self:custom.propertyTable}

functions:

  api:

    handler: index.savePhoto

    events:

      - httpApi:

          path: /

          method: post

custom: 

  propertyTable: ${self:service}-property-table-${sls:stage}

  imagesBucketName: ${self:service}-s3-${sls:stage}

resources:

  Resources:

    # S3 BUCKET

    ImagesBucket: 

      Type: AWS::S3::Bucket

      Properties:

        BucketName: ${self:custom.imagesBucketName}

        # Granting public access to bucket

        PublicAccessBlockConfiguration:

          BlockPublicAcls: false

          BlockPublicPolicy: false

          IgnorePublicAcls: false

          RestrictPublicBuckets: false

    ImagesBucketAllowPublicReadPolicy:

      Type: AWS::S3::BucketPolicy

      Properties:

        Bucket: !Ref ImagesBucket

        PolicyDocument:

          Version: "2012-10-17"

          Statement: 

            - Sid: AllowPublicReadAccess

              Effect: Allow

              Action: 

                - "s3:GetObject"

              Resource: 

                - !Join ['/', [!GetAtt [ImagesBucket, Arn], '*']]

              Principal: "*"    

              Condition:

                Bool:

                  aws:SecureTransport: 'true'

    # DynamoDB 

    PropertyTable:

      Type: AWS::DynamoDB::Table

      Properties:

        TableName: ${self:custom.propertyTable}

        AttributeDefinitions:

          - AttributeName: ID

            AttributeType: S           

        KeySchema:

          - AttributeName: ID

            KeyType: HASH

        BillingMode: PAY_PER_REQUEST

plugins:

  - serverless-offline

  - serverless-plugin-common-excludes

lambda函数代码



const AWS = require('aws-sdk')

const parser = require("lambda-multipart-parser")

const { v4: uuidv4 } = require("uuid")

const s3 = new AWS.S3();

const BucketName = process.env.BUCKET_NAME;

async function saveFile(file){

  try {

    const savedFile = await s3.putObject({

      Bucket: BucketName,

      Key: `${file.filename}-${uuidv4()}`,

      Body: file.content

    }).promise()

    return 'done'

  } catch (error) {

    return error

  }

} 

module.exports.savePhoto = async (event) => {

  const {files} = await parser.parse(event)

  const status = await saveFile(files[0])

  return {

    statusCode: 200,

    body: JSON.stringify(

      {

        message: "Go Serverless v3.0! Your function executed successfully!",

        input: 'File Uploaded',

        bucketName: BucketName,

        status: status,

        filename: files[0].filename

      },

      null,

      2

    ),

  };

};
amazon-web-services amazon-s3 aws-lambda serverless-framework aws-serverless
1个回答
0
投票

我认为您授予访问权限的 IAM 声明不完整。它仅授予对存储桶资源的访问权限,而不授予存储桶中的单个对象的访问权限。请参阅此处的文档了解如何定义它:https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html

tldr;您需要在末尾使用

/*
来指定资源

在本地工作可能是因为 IAM 检查根本没有在那里进行检查,或者您的凭证具有适当的权限

© www.soinside.com 2019 - 2024. All rights reserved.