AWS S3 Bucket - getSignedUrl PUT возвращает 400 (неверный запрос) - PullRequest
0 голосов
/ 26 октября 2018

У меня возникла странная проблема в моем проекте, где мне не удалось найти то, что я сделал неправильно.Я пытаюсь загрузить изображение в свой блог и использую конфигурацию 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>

, поэтому в моем веб-интерфейсе (в избыточном) я добавил 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

Ответы [ 2 ]

0 голосов
/ 28 октября 2018

Хорошо, после нескольких ночей страданий, я нашел решение проблемы.Помните, что AWS S3 не принимает токен на предъявителя jwt, включенный в его запрос PUT.Таким образом, вы должны отключить его при выполнении запроса.Здесь я мог бы исправить это на моем фронте, используя библиотеку 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")
}
0 голосов
/ 26 октября 2018

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",
}

Ваш мета-файл:

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

file.name! == ${req.user.id}/${uuid()}.jpeg

Вы можете изменить имя файла на стороне клиента на то же имя файла (что было сгенерировано) на стороне сервера, или использовать противоположный способ

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...