NodeJS AWS S3 Bucket - getSignedUrl PUT返回400(错误请求)

jdg4fx2g  于 2023-08-04  发布在  Node.js
关注(0)|答案(3)|浏览(156)

我得到了一个奇怪的问题,在我的项目是我不能设法找到我做错了什么。我试图上传一张图片到我的博客,我使用的是AWS S3配置,以便做到这一点。我相信我的配置是正确的,但以防万一,我会把它们添加到那里:

这里是我的cors配置

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
<CORSRule>
    <AllowedOrigin>http://localhost:3000</AllowedOrigin>
    <AllowedMethod>PUT</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

字符串
我所有的IAM策略和用户API都是有序的并且被激活的。下面是我的后端代码:

const s3 = new AWS.S3({
  accessKeyId: keys.aws.clientID,
  secretAccessKey: keys.aws.clientSecret,
  signatureVersion: "v4",
  region: "eu-west-3"
})

const router = express.Router()
// @route  GET api/posts/upload
// @desc   Upload an image on amazone server API
// @access Private
router.get(
  "/upload",
  passport.authenticate("jwt", { session: false }),
  (req, res) => {
    const key = `${req.user.id}/${uuid()}.jpeg`
    s3.getSignedUrl(
      "putObject",
      {
        Bucket: "bebeyogini",
        ContentType: "image/jpeg",
        Key: key
      },
      (err, url) => res.send({ key, url })
    )
  }
)


当我调用/upload端点时,它返回一个

<Error>
<Code>SignatureDoesNotMatch</Code>
<Message>
The request signature we calculated does not match the signature you provided. Check your key and signing method.
</Message>


这就是为什么在我的前端(在redux中)我添加了一个PUT,我在头文件中添加了内容类型文件。但在这个项目中它仍然不起作用

export const sendPost = (newPost, file, history) => async dispatch => {
  dispatch(loading())
  const uploadConfig = await axios.get("/api/posts/upload")
  console.log(uploadConfig)
  console.log(uploadConfig.data)
  await axios.put(uploadConfig.data.url, file, {
    headers: {
      "Content-Type": file.type
    }
  })
  const res = await axios.post("/api/posts", {
    ...newPost,
    imageUrl: uploadConfig.data.key
  })
  history.push("/dashboard")
  dispatch({
    type: POSTS_FETCHED,
    payload: res.data
  })
}


几个月前,我在另一个项目中成功地使aws s3工作,做了同样的配置,我在两者之间的唯一区别是,一个是用cookie会话设置的,而这个是头部中的jwt令牌。
如果有人有主意。。我完全卡住了!这里是仓库
错误状态:

bebeyogini.s3.eu-west-3.amazonaws.com/5bc0eca10743075fecb360f2/8bb4ff60-d8e7-11e8-ad9d-f776f418fd42.jpeg?Content-Type=image%2Fjpeg&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIAMYTIX267RJ5E4A%2F20181026%2Feu-west-3%2Fs3%2Faws4_request&X-Amz-Date=20181026T062242Z&X-Amz-Expires=900&X-Amz-Signature=943652af4bea7e8e0e6d0f97503ea997817e7d68e0540c599643d612d71fe693&X-Amz-SignedHeaders=host:1 PUT https://bebeyogini.s3.eu-west-3.amazonaws.com/5bc0eca10743075fecb360f2/8bb4ff60-d8e7-11e8-ad9d-f776f418fd42.jpeg?Content-Type=image%2Fjpeg&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIAMYTIX267RJ5E4A%2F20181026%2Feu-west-3%2Fs3%2Faws4_request&X-Amz-Date=20181026T062242Z&X-Amz-Expires=900&X-Amz-Signature=943652af4bea7e8e0e6d0f97503ea997817e7d68e0540c599643d612d71fe693&X-Amz-SignedHeaders=host 400 (Bad Request)
createError.js:17 Uncaught (in promise) Error: Request failed with status code 400
    at createError (createError.js:17)
    at settle (settle.js:19)
    at XMLHttpRequest.handleLoad (xhr.js:78)


https://github.com/erwanriou/bebeyogini

ccrfmcuu

ccrfmcuu1#

好吧,经过几个晚上的痛苦,我确实找到了解决问题的办法。请注意,AWS S3不接受PUT请求中包含的jwt承载令牌。所以你必须在请求时禁用它。在这里,我可以修复它在我的正面使用图书馆axios.

export const sendPost = (values, file, history) => async dispatch => {
  dispatch(loading())
  const uploadConfig = await axios.get("/api/posts/upload")
  delete axios.defaults.headers.common["Authorization"]
  await axios.put(uploadConfig.data.url, file, {
    headers: {
      ContentType: file.type
    }
  })
  const token = localStorage.getItem("jwtToken")
  axios.defaults.headers.common["Authorization"] = token
  const res = await axios.post("/api/posts", {
    ...values,
    imageUrl: uploadConfig.data.key
  })
  dispatch({
    type: POSTS_FETCHED,
    payload: res.data
  })
  history.push("/dashboard")
}

字符串

2g32fytz

2g32fytz2#

The request signature we calculated does not match the signature you provided. Check your key and signing method.这意味着您的预签名数据与您要上传的数据不匹配。
您的签名数据:

{
    Key: `${req.user.id}/${uuid()}.jpeg`
    ContentType: "image/jpeg",
}

字符串
您的文件Meta:

{
    Name: file.name
    ContentType: "image/jpeg",
}


file.name!== ${req.user.id}/${uuid()}.jpeg
您可以将客户端的文件名更改为服务器端的相同文件名(已生成的文件名),或者使用相反的方法

snvhrwxg

snvhrwxg3#

由于axios有JWT,导致400错误。为了避免这种情况,我们可以使用JavaScript获取API。
打击是暗号

const formData = new FormData();
    formData.append("file", file[0]);

const requestOptions = {
      method: "PUT",
      body: formData,
      redirect: "follow",
    };

const response = await fetch(presignedPutRequestUrl, requestOptions);

字符串
或使用transformRequest

await axios.put(putRequestUrl, file[0], {
      transformRequest: [
        (data, headers) => {
          delete headers.Authorization;
          return data;
        },
      ],
    });

相关问题