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 PointNet++的onnx模型只能使用一次
  • ¥20 西南科技大学数字信号处理
  • ¥15 有两个非常“自以为是”烦人的问题急期待大家解决!
  • ¥30 STM32 INMP441无法读取数据
  • ¥15 R语言绘制密度图,一个密度曲线内fill不同颜色如何实现
  • ¥100 求汇川机器人IRCB300控制器和示教器同版本升级固件文件升级包
  • ¥15 用visualstudio2022创建vue项目后无法启动
  • ¥15 x趋于0时tanx-sinx极限可以拆开算吗
  • ¥500 把面具戴到人脸上,请大家贡献智慧,别用大模型回答,大模型的答案没啥用
  • ¥15 任意一个散点图自己下载其js脚本文件并做成独立的案例页面,不要作在线的,要离线状态。