首页 > 解决方案 > 如何使用 Amazonka 获取签名的 put 对象 url

问题描述

我正在尝试获取一个预签名的 url 来将一个对象放入我的 s3 存储桶。我知道存储桶配置很好,因为我已经在 node 上多次使用它并且没有任何问题。我目前正在尝试将我的上传端点转换为一个 haskell 端点作为个人项目。

我尝试使用 amazonka 来进行此操作,但是我不断收到来自 AWS 的错误消息,并且我无法找到有关如何完成此操作的好教程。我收到的错误消息如下:

您尝试访问的存储桶必须使用指定的端点进行寻址。请将所有未来的请求发送到此端点。

我收到一个包含以下内容的网址: https://s3.amazonaws.com/(my-bucket-name)

所以我把它改成这样: https://(my-bucket-name).s3.us-east-2.amazonaws.com 修复上述问题的前缀后,我得到以下信息:

解析 X-Amz-Credential 参数时出错;区域“us-east-1”是错误的;期待'us-east-2'

但是我正在设置我的密钥、访问密钥和存储桶。

这是一个可重现的示例:

module Lib
    ( main
    ) where

import ClassyPrelude
import           Network.AWS.S3
import           Network.AWS.S3.PutObject
import           Control.Monad.Trans.AWS
import           Network.AWS.Data
import           Control.Lens

bNameE :: BucketName
bNameE = BucketName <my-bucket-name>

oKeyE :: ObjectKey
oKeyE = ObjectKey ("101/12345-12345-12345-12345.jpg")
-- oKeyE = ObjectKey "photo-106399.jpeg"

sKeyE :: Text
sKeyE = <my-bucket-secret>

aKeyE :: Text
aKeyE = <my-bucket-public>

main :: IO ()
main = do
  r <- getPresignedURL Ohio bNameE oKeyE
  print r

getPresignedURL :: Region
                -> BucketName
                -> ObjectKey
                -> IO ByteString
getPresignedURL r b k = do
    lgr <- newLogger Trace stdout
    env <- newEnv $ FromKeys (AccessKey $ encodeUtf8 $ aKeyE) (SecretKey $ encodeUtf8 $ sKeyE)
    ts  <- getCurrentTime
    let p = (putObject b k "") -- & poContentType .~ (Just "Content-Type=image/jpeg")
    print p
    runResourceT . runAWST env $
        presignURL ts 900 p --(poContentType (Lens'  (Just "Content-Type=jpeg")))

标签: haskellamazon-s3

解决方案


该问题是基于未在 Env 变量内设置区域,您可以使用以下内容生成签名 URL:

getPresignedURL :: Region
                -> BucketName
                -> ObjectKey
                -> IO ByteString
getPresignedURL r b k = do
    lgr <- newLogger Trace stdout
    env <- newEnv $ FromKeys (AccessKey $ encodeUtf8 $ aKeyE) (SecretKey $ encodeUtf8 $ sKeyE)
    let nEnv = env & envRegion .~ r
    ts  <- getCurrentTime 
    runResourceT . runAWST nEnv $ presignURL ts 900 (putObject b k "Content-Type=image/jpeg")

我对镜头不是很熟悉,所以我相信有一种更简洁的方法可以做到以下几点:

    env <- newEnv $ FromKeys (AccessKey $ encodeUtf8 $ aKeyE) (SecretKey $ encodeUtf8 $ sKeyE)
    let nEnv = env & envRegion .~ r

推荐阅读