When you create an object in s3, by default it is private. If you access an object url, you should see
```
AccessDenied
Access Denied
0E7531544D92C793
wCC8lVp1Yqnjl2ItHuFxhAKCr2IWLziOavoWyif/Spn1WVsHUyTHEK3vckTK49Kmy/M/YIHQvQ4=
```
If you need to share the object to other people without making it public, you can control the access using a fine-grained IAM policy or use presigned url to grant your users temporary access to a specific object.
In this post, you will learn how to generate a s3 presigned url in Go.
First, let's import some packages that will be used
```
import (
"fmt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
"time"
)
```
Create a function which takes three parameters - bucket, key and region. It returns the presigned url at the end.
```
func GetS3PresignedUrl(bucket string, key string, region string, expiration time.Duration) string{
// TODO
}
```
Initialize a session in the target region that the SDK will use to load credentials from the shared credentials file ``~/.aws/credentials``.
```
sess, err := session.NewSession(&aws.Config{
Region: aws.String(region)},
)
```
Create S3 service client
```
svc := s3.New(sess)
```
Construct a new GetObjectRequest
```
req, _ := svc.GetObjectRequest(&s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
})
```
Create a presigned url with expiration time
```
presignedUrl, err := req.Presign(expiration * time.Minute)
```
Check if it can be presigned or not
```
if err != nil {
fmt.Println("Failed to sign request", err)
}
```
Return the presigned URL
```go
return presignedUrl
```
You can find the complete code [here](https://gist.github.com/wingkwong/a7a33fee0b640997991753d9f06ff120)
Let's have a quick test
```
S3PresignedUrl.GetS3PresignedUrl("test-s3-presigned-url-s2kvn2bs", "d4fb43054862c768921504199c78958b.jpg", "ap-southeast-1", 15)
```
The ``presignedUrl`` is
```
https://test-s3-presigned-url-s2kvn2bs.s3.ap-southeast-1.amazonaws.com/d4fb43054862c768921504199c78958b.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAW4RRUVRQTI2J564J%2F20191227%2Fap-southeast-1%2Fs3%2Faws4_request&X-Amz-Date=20191227T055220Z&X-Amz-Expires=900&X-Amz-SignedHeaders=host&X-Amz-Signature=ed1d94edd580976f0175eca1c4c1944a9f215fd572540e3e3c7ed1c317656358
```
If we break it down, the presigned url contains ``X-Amz-Algorithm``, ``X-Amz-Credential``, ``X-Amz-Date``, ``X-Amz-Expires`` and ``X-Amz-Signature``. These are AWS Signature Version 4 query parameters.
```
https://test-s3-presigned-url-s2kvn2bs.s3.ap-southeast-1.amazonaws.com/d4fb43054862c768921504199c78958b.jpg
?X-Amz-Algorithm=AWS4-HMAC-SHA256
&X-Amz-Credential=AKIAW4RRUVRQTI2J564J%2F20191227%2Fap-southeast-1%2Fs3%2Faws4_request
&X-Amz-Date=20191227T055220Z
&X-Amz-Expires=900&X-Amz-SignedHeaders=host
&X-Amz-Signature=ed1d94edd580976f0175eca1c4c1944a9f215fd572540e3e3c7ed1c317656358
```
Browse the presigned url
![image](https://user-images.githubusercontent.com/35857179/71507355-36b64180-28bf-11ea-8796-e86f4a48e8fc.png)
After the expiration time, you will see the below message
```
AccessDenied
Request has expired
900
2019-12-27T06:07:20Z
2019-12-27T07:13:10Z
805E5BD14FFAEA84
My9ZyJNtcixWAu91g79KVomutCU2AE4cj8G2eQo4KERAm/AoRxzppIZfXs5Cw+cuhuyo8eFgtvY=
```
Complete Code: [https://gist.github.com/wingkwong/a7a33fee0b640997991753d9f06ff120](https://gist.github.com/wingkwong/a7a33fee0b640997991753d9f06ff120)
No comments:
Post a Comment