Thursday 2 January 2020

Generating an S3 Presigned URL in Go

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

A Fun Problem - Math

# Problem Statement JATC's math teacher always gives the class some interesting math problems so that they don't get bored. Today t...