阿里云对象存储OSS的请求者付费模式是指由请求者支付读取存储空间(Bucket)内数据时产生的流量费用和请求费用,而Bucket拥有者仅支付存储费用。当您希望共享数据,但又不希望产生流量费用和请求费用时,您可以开启此功能。

请求方式说明

  • 不允许匿名访问

    如果您在Bucket启用了请求者付费模式,则不允许匿名访问该Bucket。请求方必须提供身份验证信息,以便OSS能够识别请求方,从而对请求方而非Bucket拥有者收取请求所产生的费用。

    当请求者是通过扮演阿里云RAM角色来请求数据时,该角色所属的账户将为此请求付费。

  • 申请方需携带x-oss-request-payer信息

    如果您在Bucket上启用了请求者付费模式,请求方必须在其请求中包含x-oss-request-payer:requester (在PUT、POST、GET和HEAD请求的Head信息中),以表明请求方知道请求和数据下载将产生费用。否则,请求方无法通过验证。

    数据拥有者访问该Bucket时,可以不携带x-oss-request-payerundefined请求头。数据拥有者作为请求者访问该Bucket时,请求产生的费用由数据拥有者(也是请求者)来支付。

有关请求者付费模式的详情,请参考开发指南的请求者付费模式

设置请求者付费模式

以下代码用于设置请求者付费模式:
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* 初始化OSS账号信息 */
    std::string AccessKeyId = "yourAccessKeyId";
    std::string AccessKeySecret = "yourAccessKeySecret";
    std::string Endpoint = "yourEndpoint";
    std::string BucketName = "yourBucketName";

    /* 初始化网络等资源 */
    InitializeSdk();

    ClientConfiguration conf;
    OssClient client(Endpoint, AccessKeyId, AccessKeySecret, conf);

    /* 设置请求者付费模式 */
    SetBucketRequestPaymentRequest request(BucketName);
    request.setRequestPayer(RequestPayer::Requester);

    auto outcome = client.SetBucketRequestPayment(request);

    if (!outcome.isSuccess()) {
        /* 异常处理 */
        std::cout << "SetBucketRequestPayment fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        ShutdownSdk();
        return -1;
    }

    /* 释放网络等资源 */
    ShutdownSdk();
    return 0;
}

获取请求者付费模式

以下代码用于获取请求者付费模式:
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* 初始化OSS账号信息 */
    std::string AccessKeyId = "yourAccessKeyId";
    std::string AccessKeySecret = "yourAccessKeySecret";
    std::string Endpoint = "yourEndpoint";
    std::string BucketName = "yourBucketName";

    /* 初始化网络等资源 */
    InitializeSdk();

    ClientConfiguration conf;
    OssClient client(Endpoint, AccessKeyId, AccessKeySecret, conf);

    /* 获取请求者付费模式 */
    GetBucketRequestPaymentRequest request(BucketName)
    auto outcome = client.GetBucketRequestPayment(request);

    if (outcome.isSuccess())
    {
        std::cout << "GetBucketRequestPayment success Payer:" << outcome.result().Payer() << std::endl;
    }
    else {
        /* 异常处理 */
        std::cout << "GetBucketPayment fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        ShutdownSdk();
        return -1;
    }

    /* 释放网络等资源 */
    ShutdownSdk();
    return 0;
}

第三方付费访问Object

设置请求者付费模式后,您可以使用Bucket Policy授权其他用户访问OSS资源,或者通过企业控制台的外部账号设置授权第三方访问,详情请参考教程示例:基于企业控制台外部人员实现跨账号访问OSS
说明 第三方操作Object时需在http header中携带x-oss-request-payer:requester参数,否则会报错。

以下代码以PutObject、GetObject及DeleteObject为例,用于指定第三方付费访问Object。

其他用于指定第三方付费的Object读写操作接口设置方法类似。

以下代码用于设置第三方付费访问Object:
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* 初始化OSS账号信息 */
    std::string AccessKeyId = "yourAccessKeyId";
    std::string AccessKeySecret = "yourAccessKeySecret";
    std::string Endpoint = "yourEndpoint";
    std::string PayerAccessKeyId = "yourPayerAccessKeyId";
    std::string PayerAccessKeySecret = "yourPayerAccessKeySecret";
    std::string PayerEndpoint = "yourPayerEndpoint";
    std::string BucketName = "yourBucketName";
    std::string PayerUID = "PayerUID";
    std::string ObjectName = "yourObjectName";


    /* 初始化网络等资源 */
    InitializeSdk();

    ClientConfiguration conf;
    OssClient client(Endpoint, AccessKeyId, AccessKeySecret, conf);
    OssClient payerClient(PayerEndpoint, PayerAccessKeyId, PayerAccessKeySecret, conf);

    /* 创建bucket */
    CreateBucketOutcome outCome = client.CreateBucket(CreateBucketRequest(BucketName));

    /* 设置请求者付费模式 */
    SetBucketRequestPaymentRequest request(BucketName);
    request.setRequestPayer(RequestPayer::Requester);
    auto payoutcome = client.SetBucketRequestPayment(request);

    /* 上传文件,并设置请求者付费 */
    *content << "test cpp sdk";
    PutObjectRequest putrequest(BucketName, ObjectName, content);
    putrequest.setRequestPayer(RequestPayer::Requester);
    auto putoutcome = payerClient.PutObject(putrequest);

    /* 获取文件到本地内存,并设置请求者付费 */
    GetObjectRequest getrequest(BucketName, ObjectName);
    getrequest.setRequestPayer(RequestPayer::Requester);
    auto getoutcome = payerClient.GetObject(getrequest);

    /* 删除文件,并设置请求者付费 */
    DeleteObjectRequest delrequest(BucketName, ObjectName);
    delrequest.setRequestPayer(RequestPayer::Requester);
    auto deloutcome = payerClient.DeleteObject(delrequest);

    /* 释放网络等资源 */
    ShutdownSdk();
    return 0;
}