drpkcwwav20524605 2016-07-07 03:20
浏览 48
已采纳

无法在App Engine中创建签名的URL

I'm trying to create a signed URL to download a file in Google Cloud Storage, from an App Engine app written in Go. There's a nifty signing method in App Engine which I'm using, which [in theory] allows me to avoid putting a private key in my app. However, the URLs don't appear to work: I always get a 403 "SignatureDoesNotMatch" error. Any ideas?

Here's the code:

func createDownloadURL(c context.Context, resource string, validUntil time.Time, bucket string) (string, error) {
  serviceAccount, err := appengine.ServiceAccount(c)
  if err != nil {
    return "", err
  }

  // Build up the string to sign.
  validUntilString := strconv.FormatInt(validUntil.Unix(), 10)
  toSign := []string{
    "GET",            // http verb (required)
    "",               // content MD5 hash (optional)
    "",               // content type (optional)
    validUntilString, // expiration (required)
    resource,         // resource (required)
  }

  // Sign it.
  _, signedBytes, err := appengine.SignBytes(c, []byte(strings.Join(toSign, "
")))
  if err != nil {
    return "", err
  }
  signedString := base64.StdEncoding.EncodeToString(signedBytes)

  // Build and return the URL.
  arguments := url.Values{
    "GoogleAccessId": {serviceAccount},
    "Expires":        {validUntilString},
    "Signature":      {signedString},
  }
  return fmt.Sprintf("https://storage.googleapis.com/%s/%s?%s", bucket, resource, arguments.Encode()), nil
}
  • 写回答

3条回答 默认 最新

  • douyuan6490 2016-07-07 15:20
    关注

    Solved. There were 2 problems with my code.

    I forgot to include the bucket name when building up toSign. Fix:

    fmt.Sprintf("/%s/%s", bucket, resource),         // resource (required)
    

    This returned an AccessDenied error -- progress!

    The second mistake was using the XML API storage.googleapis.com instead of the authenticated browser endpoint storage.cloud.google.com. Fix:

    return fmt.Sprintf("https://storage.cloud.google.com/%s/%s?%s", bucket, resource, arguments.Encode()), nil
    

    This works.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 孟德尔随机化结果不一致
  • ¥15 深度学习残差模块模型
  • ¥50 怎么判断同步时序逻辑电路和异步时序逻辑电路
  • ¥15 差动电流二次谐波的含量Matlab计算
  • ¥15 Can/caned 总线错误问题,错误显示控制器要发1,结果总线检测到0
  • ¥15 C#如何调用串口数据
  • ¥15 MATLAB与单片机串口通信
  • ¥15 L76k模块的GPS的使用
  • ¥15 请帮我看一看数电项目如何设计
  • ¥23 (标签-bug|关键词-密码错误加密)