javascript - 如何使用 Node/Typescript 获得签名的 S3 url?

标签 javascript typescript amazon-s3 graphcool

在 FaaS 中使用 Node + aws-sdk,我尝试获取预签名 URL 以将文件上传到 S3 存储桶。当我上传文件时,我收到以下响应

InvalidAccessKeyId您提供的 AWS 访问 key ID 在我们的记录中不存在。

// getUploadUrl
import { FunctionEvent } from 'graphcool-lib'
import * as AWS from 'aws-sdk'

const BUCKET = process.env['BUCKET'];
const AWS_ACCESS_KEY_ID = process.env['AWS_ACCESS_KEY_ID'];
const AWS_SECRET_ACCESS_KEY = process.env['AWS_SECRET_ACCESS_KEY'];

const signedUrlExpiresSeconds = 60*10;

AWS.config.update({
  accessKeyId: AWS_ACCESS_KEY_ID,
  secretAccessKey: AWS_SECRET_ACCESS_KEY,
  region: 'eu-west-2'
});

const s3 = new AWS.S3({ apiVersion: "2006-03-01" })

interface EventData {
  fileName: string
}

export default async (event: FunctionEvent<EventData>) => {

  if (!event.context.auth || !event.context.auth.nodeId) {
    return { error: 'No user logged in.' }
  }

  try {
    const { fileName } = event.data;

    // Pre-signing a putObject (asynchronously)
    const params = { Bucket: BUCKET, Key: fileName, Expires: signedUrlExpiresSeconds }
    const uploadUrl: string = await s3.getSignedUrl('putObject', params)

    if (!uploadUrl) {
      return { error: 'Unable to get presigned upload URL from S3' }
    }



    return { data: { uploadUrl } }
  } catch (e) {
    console.log(e)
    return { error: 'An unexpected error occured during password change.' }
  }
}

以下是我对 AWS IAM 的权限

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject"
            ],
            "Resource": "arn:aws:s3:::bucket-name/*"
        }
    ]
}

我使用以下方式上传文件

curl -v -T test.pdf presignedUrl

有什么想法吗?

这是生成的路径

"https://my-aws-s3-domain.s3.eu-west-2.amazonaws.com/test.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=XXXXXXX1222%2Feu-west-2%2Fs3%2Faws4_request&X-Amz-Date=20171222T153846Z&X-Amz-Expires=600&X-Amz-Signature=XXXXXX-268d&X-Amz-SignedHeaders=host"

我将 AWS 配置更新为 AWS.config.update({ Region: 'eu-west-2' }); 因为它会自动从 process.ENV 中获取 AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY (正如迈克尔所指出的)。

我再次尝试,收到拒绝访问响应,因此我将 IAM 策略更改为:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::my-s3-bucket-name"
        }
    ]
}

它仍然给出访问被拒绝的错误。

最佳答案

事实证明 Graphcool 的环境变量存在错误,这意味着 AWS key 没有更新。

可能与此问题相关: https://github.com/graphcool/framework/issues/799

编辑 - 在 Graphcool 中,AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY 是 protected 环境变量。所以你不能使用它们

关于javascript - 如何使用 Node/Typescript 获得签名的 S3 url?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47940887/

相关文章:

java - Amazon s3 只为一个桶返回 1000 个条目,而为另一个桶返回所有条目(使用 java sdk)?

javascript - 如何在php中找到与某个字符最接近的html标签?

javascript - 在 typescript 中使用任何 Prop 定义对象

javascript - 如何传递数字 id 而不是字符串 id?

rest - 如何在命令行中使用版本从 AWS S3 下载文件?

amazon-s3 - AWS CLI 如何查询同一元素的多个参数?

javascript - jQuery/javascript 替换标签类型

Javascript:使两个div相同高度

javascript - 如何按值将最后一项推送到 RxJs/BehaviorSubject?

javascript - Angular 5 - 如何重定向到具有特定 header 的外部 URL?