All Products
Search
Document Center

Object Storage Service:Use OSS SDK for Go to upload an object by including signatures in the Authorization header

Last Updated:Mar 20, 2026

This example shows how to use OSS SDK for Go 1.7.6 to upload an object by constructing an Authorization header with an HMAC-SHA1 signature.

How it works

The upload request is an HTTP PUT with three required headers:

HeaderValue
Content-TypeThe media type of the object, for example application/json
DateThe current UTC time in HTTP date format
AuthorizationOSS <AccessKeyId>:<signature>

To build the signature:

  1. Construct the string to sign using the following format:

    ComponentDescription
    PUTHTTP method
    \n\nTwo newlines: the first follows the HTTP method, the second replaces the empty Content-MD5 field
    <Content-Type>The value of the Content-Type header
    <Date>The value of the Date header in HTTP date format (UTC)
    /<bucket>/<object>The canonical resource path. Do not include the bucket name in the object path.
       PUT\n\n<Content-Type>\n<Date>\n/<bucket>/<object>
  2. Compute HMAC-SHA1 over the string to sign, using your AccessKey Secret as the key.

  3. Base64-encode the HMAC-SHA1 digest to produce the signature.

  4. Set the Authorization header to OSS <AccessKeyId>:<signature>.

Prerequisites

Before you run the example, set the following environment variables:

VariableDescription
OSS_ACCESS_KEY_IDYour AccessKey ID
OSS_ACCESS_KEY_SECRETYour AccessKey Secret

Reading credentials from environment variables avoids hardcoding sensitive values in source code.

Example

The following example uploads an object to OSS using a manually constructed Authorization header.

package main

import (
  "crypto/hmac"
  "crypto/sha1"
  "encoding/base64"
  "fmt"
  "io/ioutil"
  "net/http"
  "os"
  "strings"
  "time"
)

func main() {
  // Specify the name of the bucket. Example: examplebucket.
  bucketname := "examplebucket"
  // Specify the public endpoint of the bucket.
  endpoint := "oss-cn-hangzhou.aliyuncs.com"
  // Specify the full path of the object. Do not include the bucket name in the full path. Example: example/test.txt.
  objectname := "examplefile.txt"
  // Read access credentials from environment variables.
  // Before you run the code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are set.
  accesskey := os.Getenv("OSS_ACCESS_KEY_ID")
  accesskeysecret := os.Getenv("OSS_ACCESS_KEY_SECRET")
  contenttype := "application/json"
  gmtdate := time.Now().UTC().Format(http.TimeFormat)
  stringtosign := "PUT\n\n" + contenttype + "\n" + gmtdate + "\n" + "/" + bucketname + "/" + objectname

  key := []byte(accesskeysecret)
  mac := hmac.New(sha1.New, key)
  mac.Write([]byte(stringtosign))
  // Base64-encode the HMAC-SHA1 digest.
  signature := base64.StdEncoding.EncodeToString(mac.Sum(nil))

  url := "http://" + bucketname + "." + endpoint + "/" + objectname

  payload := strings.NewReader("{go:test}")

  req, _ := http.NewRequest("PUT", url, payload)

  req.Header.Add("Content-Type", contenttype)
  req.Header.Add("Authorization", "OSS "+accesskey+":"+signature)
  req.Header.Add("Date", gmtdate)
  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}

A successful response returns HTTP 200 and looks similar to:

&{200 OK 200 HTTP/1.1 1 1 map[Connection:[keep-alive] Content-Length:[0] Content-Md5:[BBFHkvGJ4s7YGacim2mbCg==] Date:[Thu, 14 Sep 2023 09:28:19 GMT] Etag:["04114792F189E2CED819A7229B69****"] Server:[AliyunOSS] X-Oss-Hash-Crc64ecma:[1342951013225723****] X-Oss-Request-Id:[6502D233818A31353126****] X-Oss-Server-Time:[126]] {} 0 [] false false map[] 0xc000134000 <nil>}

What's next