You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS预签名URL设6天有效期却1小时失效,求调试指引

调试AWS预签名URL有效期不符问题的思路

以下是你的AWS客户端初始化及预签名URL生成代码:

客户端初始化代码

type AWSClient struct {
    uploader   *manager.Uploader
    downloader *manager.Downloader
    psClient   *s3.PresignClient
    s3Client   *s3.Client
    sesClient  *sesv2.Client
}

func NewAWSClient() AWSClient {
    log.Println("Configuring AWS ...")

    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatal(err)
        panic("Error configuring AWS.")
    }

    s3Client := s3.NewFromConfig(cfg)
    sesClient := sesv2.NewFromConfig(cfg)

    return AWSClient{
        s3Client:   s3Client,
        uploader:   manager.NewUploader(s3Client),
        downloader: manager.NewDownloader(s3Client),
        psClient:   s3.NewPresignClient(s3Client),
        sesClient:  sesClient,
    }
}

预签名URL生成代码

func (c AWSClient) GetPresignedURL(ctx context.Context, awsBucket string, key string, ttl time.Duration) (string, entity.Error) {
    logger := rctx.LoggerWithFn(ctx)

    input := &s3.GetObjectInput{
        Key:    &key,
        Bucket: &awsBucket,
    }

    resp, err := c.psClient.PresignGetObject(context.TODO(), input, s3.WithPresignExpires(ttl)) // 6 days expiry.
    if err != nil {
        logger.Log(p.Error, "error retrieving pre-signed object: "+err.Error())
        return "", entity.InternalError(err)
    }

    return resp.URL, nil
}

针对设置6天有效期但实际1小时过期的问题,可按以下思路调试:

  • 验证TTL参数传递正确性
    在GetPresignedURL函数开头添加日志,打印传入的ttl具体值,确认是否确实为6天(即6*24*time.Hour)。同时检查上层调用代码,确认参数未被错误覆盖为1小时。示例日志代码:

    logger.Log(p.Info, fmt.Sprintf("Requested TTL: %v", ttl))
    
  • 检查凭证有效期限制
    若使用临时凭证(如IAM角色、STS凭证),预签名URL的有效期不能超过凭证本身的过期时间。很多临时凭证默认有效期为1小时,此时即使设置更长TTL,URL实际有效期也会被限制为凭证剩余时长。可在客户端初始化时打印凭证过期时间:

    creds, err := cfg.Credentials.Retrieve(context.TODO())
    if err == nil {
        log.Printf("Credential expiry: %v", creds.Expires)
    }
    
  • 解析预签名URL的过期参数
    查看生成的URL中X-Amz-Expires参数值(单位为秒),6天对应518400秒,若该值为3600(1小时),说明SDK未正确应用设置的TTL。可打印URL的查询参数确认:

    logger.Log(p.Info, fmt.Sprintf("Presigned URL query params: %s", resp.URL.RawQuery))
    
  • 排查PresignClient配置
    确认创建PresignClient时未设置默认过期时间覆盖后续参数。当前代码中NewPresignClient无额外配置,但若后续修改时传入了自定义PresignOptions并设置了Expires,会导致所有预签名URL使用该默认值。

  • 测试最小化场景
    编写独立测试程序,直接初始化客户端并生成预签名URL,排除业务代码中的干扰因素。如果测试程序能生成正确有效期的URL,说明问题出在业务逻辑的参数传递或上下文处理环节。示例测试代码:

    package main
    
    import (
        "context"
        "fmt"
        "log"
        "time"
    
        "github.com/aws/aws-sdk-go-v2/config"
        "github.com/aws/aws-sdk-go-v2/service/s3"
    )
    
    func main() {
        cfg, err := config.LoadDefaultConfig(context.TODO())
        if err != nil {
            log.Fatal(err)
        }
    
        s3Client := s3.NewFromConfig(cfg)
        psClient := s3.NewPresignClient(s3Client)
    
        input := &s3.GetObjectInput{
            Key:    aws.String("test-key"),
            Bucket: aws.String("test-bucket"),
        }
    
        ttl := 6 * 24 * time.Hour
        resp, err := psClient.PresignGetObject(context.TODO(), input, s3.WithPresignExpires(ttl))
        if err != nil {
            log.Fatal(err)
        }
    
        fmt.Printf("Presigned URL: %s\n", resp.URL)
        fmt.Printf("X-Amz-Expires: %s\n", resp.URL.Query().Get("X-Amz-Expires"))
    }
    
  • 检查存储桶策略限制
    虽然少见,但部分Bucket Policy可能通过Condition项限制x-amz-expires的值,需确认存储桶策略未添加此类限制。

内容的提问来源于stack exchange,提问作者RajdeepPal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 18:14:51