英文:
How to : Invoke API Gateway endpoint with IAM authorization using golang client
问题
似乎很简单,但我还没有弄清楚。
在下面的代码中 -
resp, err := http.Get("API Gateway endpoint url goes here")
if err != nil {
log.Fatalln(err)
}
我不确定如何告诉http.get使用AWS身份验证。aws cli已在主机上配置了访问密钥和密钥。所以我不想在代码中再次提及。
一些帖子提到了签署请求。但我不确定这是否是正确的方法。考虑到golang中的AWS SDK,这感觉有点底层。我期望:
- AWS SDK中一定有一种方式来封装签署HTTP请求等操作并完成工作
- 通过“某种方式”使用内置的http包来完成这个操作
非常感谢任何帮助!
谢谢
Sandeep
英文:
It seems pretty straight forward, but I am not able to figure out yet.
In the code such as below -
resp, err := http.Get("API Gateway endpoint url goes here")
if err != nil {
log.Fatalln(err)
}
I am not sure how I tell http.get to use AWS auth. aws cli is configured the access key and secret on the host. So I do not want to again mention in the code.
Some posts mentioned about signing request. But I am not sure if that's the right way. In light of the AWS SDK in golang, this feels bit low level stuff.
I would expect either
- There must a way in AWS SDK that encapsulates signing HTTP request etc. and does the job
- There must be a way to do this using http inbuild package by "somehow" attaching aws creds.
Any help is much, much appreciated!
Thanks
Sandeep
答案1
得分: 1
一些帖子提到了签名请求,但我不确定是否是正确的方法。
是的,IAM Auth需要请求签名(请参阅文档这里和这里)。当前的方法是Signature v4。Api Gateway接受请求如果它具有预期的头部。"Signing"是添加正确头部的过程:
# signature is derived from your secret key and the request contents.
--header 'Authorization: AWS4-HMAC-SHA256 Credential=AKIASIAXTWO8D5GSN4CS/20220712/us-east-1/execute-api/aws4_request, SignedHeaders=host;x-amz-date, Signature=f2d8478ceff83d5cd0696502cb58a8331304846d11367d74608295c7acbfba0c'
# date prevents third parties from intercepting your request and resubmitting it later
--header 'X-Amz-Date: 20220712T124302Z'
肯定有一种方式在AWS SDK中封装签名HTTP请求等,并完成工作。
对于几种语言(JS、Java等,但不包括Go),get-sdk命令可以为您的Rest API生成SDK客户端,其中包括其他便利功能,包括封装签名过程:client.privateGet(params, body, additionalParams)
。
肯定有一种方法可以使用内置的http包通过"某种方式"附加AWS凭证来实现这一点。
使用普通的SDK需要更多的工作来添加头部,可以轻松地封装在可重用的类型中:
ctx := context.TODO()
// define the request
endpoint := "https://cbi3vltq21.execute-api.us-east-1.amazonaws.com"
u, _ := url.ParseRequestURI(endpoint)
u.Path = "prod/private"
req, _ := http.NewRequest("GET", u.String(), nil)
// get the credentials from the local config files
cfg, _ := config.LoadDefaultConfig(ctx,
config.WithRegion("us-east-1"),
config.WithSharedConfigProfile("my-profile"))
creds, _ := cfg.Credentials.Retrieve(ctx)
// hash the request body - hex value used in the signature
hash := sha256.Sum256([]byte("")) // if the request has no body, use the empty string
hexHash := fmt.Sprintf("%x", hash)
// add the Authorization and X-Amz-Date headers to the request
signer := v4.NewSigner()
_ = signer.SignHTTP(ctx, creds, req, hexHash, "execute-api", cfg.Region, time.Now())
// execute the request
client := &http.Client{}
resp, _ := client.Do(req)
感谢这个SO答案。
英文:
> Some posts mentioned signing requests. But I am not sure if that's the right way
Yes, IAM Auth requires request signing (see docs here and here). The current method is Signature v4. Api Gateway accepts a request if it has the expected headers. "Signing" is the process of adding the right headers:
# signature is derived from your secret key and the request contents.
--header 'Authorization: AWS4-HMAC-SHA256 Credential=AKIASIAXTWO8D5GSN4CS/20220712/us-east-1/execute-api/aws4_request, SignedHeaders=host;x-amz-date, Signature=f2d8478ceff83d5cd0696502cb58a8331304846d11367d74608295c7acbfba0c'
# date prevents third parties from intercepting your request and resubmitting it later
--header 'X-Amz-Date: 20220712T124302Z'
> There must a way in AWS SDK that encapsulates signing HTTP request etc. and does the job
For several languages (JS, Java, etc. but not Go), the get-sdk command can generate a SDK client for your Rest API that, among other conveniences, wraps the signature process: client.privateGet(params, body, additionalParams)
.
> There must be a way to do this using http inbuild package by "somehow" attaching aws creds
Using the plain-old SDKs it's a bit more work to add the headers, easily wrappable in a resusable type:
ctx := context.TODO()
// define the request
endpoint := "https://cbi3vltq21.execute-api.us-east-1.amazonaws.com"
u, _ := url.ParseRequestURI(endpoint)
u.Path = "prod/private"
req, _ := http.NewRequest("GET", u.String(), nil)
// get the credentials from the local config files
cfg, _ := config.LoadDefaultConfig(ctx,
config.WithRegion("us-east-1"),
config.WithSharedConfigProfile("my-profile"))
creds, _ := cfg.Credentials.Retrieve(ctx)
// hash the request body - hex value used in the signature
hash := sha256.Sum256([]byte("")) // if the request has no body, use the empty string
hexHash := fmt.Sprintf("%x", hash)
// add the Authorization and X-Amz-Date headers to the request
signer := v4.NewSigner()
_ = signer.SignHTTP(ctx, creds, req, hexHash, "execute-api", cfg.Region, time.Now())
// execute the request
client := &http.Client{}
resp, _ := client.Do(req)
H/T to this SO answer.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论