Authorization with Spaces using Go

September 27, 2017 159 views
Go API Object Storage

Hello, I'm need a little help with getting all the headers setup so I can get to using Spaces.

I'm doing all of this in Go and I have a few questions.

What would I set the SignedHeaders to, I see in the api docs it has it set to host;x-amz-acl;x-amz-content-sha256;x-amz-date but I'm not familiar and now sure if that changes depending on what you're doing or not.

My next question has to do with the Signature, again not 100% on the terminology used and would like a little help getting that going. So if anyone could help me out, that would be great.

Here is the code I currently have:

func SetAuthHeaders(accessKey, yymmdd, region string, req *http.Request) {

    credentials := fmt.Sprintf("%v/%v/%v/s3/aws4_request", accessKey, yymmdd, region)
    signedHeaders := "host;x-amz-acl;x-amz-content-sha256;x-amz-date"
    signature := fmt.Sprintf("")

    req.Header.Add("Authorization", "AWS4-HMAC-SHA256")
    req.Header.Add("Credential", credentials)
    req.Header.Add("SignedHeaders", signedHeaders)
    req.Header.Add("Signature", signature)
}

Thanks

1 Answer

Hey Matt! Spaces was designed to be API compatible with AWS's S3 API. One trade off with this approach is that the AWS signature formats can be a bit complicated. Though the main reason we went that direct was to allow people to use pre-existing tools. So, I'd encourage you to use one of the existing libraries for working S3-compatible APIs like minio-go or AWS' Go SDK.

Here's a quick example using minio-go:

package main

import (
    "fmt"
    "log"
    "os"

    "github.com/minio/minio-go"
)

func main() {
    accessKey := os.Getenv("DO_ACCESS_KEY")
    secKey := os.Getenv("DO_SECRET_ACCESS_KEY")
    ssl := true

    // Initiate a client using DigitalOcean Spaces.
    client, err := minio.New("nyc3.digitaloceanspaces.com", accessKey, secKey, ssl)
    if err != nil {
        log.Fatal(err)
    }

    // Create a new Space.
    err = client.MakeBucket("my-new-space", "nyc3")
    if err != nil {
        log.Fatal(err)
    }

    // List all Spaces.
    spaces, err := client.ListBuckets()
    if err != nil {
        log.Fatal(err)
    }
    for _, space := range spaces {
        fmt.Println(space.Name)
    }
}
Have another answer? Share your knowledge.