cos js sdk上传报AccessDenied?

  • 回答 (3)
  • 关注 (0)
  • 查看 (707)

通过获取临时secretId的方式上传,可以成功获取临时的secretId和secretKey,但是前端上传是报AccessDenied.

下面前端代码

//生成随机文件名    
function genFileName() {
        var text = "";
        var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";

        for (var i = 0; i < 25; i++) {
            text += possible.charAt(Math.floor(Math.random() * possible.length));
        }
        return text;
    }

    var Bucket = 'test-123456';
    var Region = 'ap-beijing';
    var prefix = 'demo';

    // 初始化实例
    var cos = new COS({
        getAuthorization: function (options, callback) {
            var fileName;
            // 异步获取签名
            $.get('/temp-secret', function (data) {
                callback({
                    TmpSecretId: data.tmpSecretId,
                    TmpSecretKey: data.tmpSecretKey,
                    XCosSecurityToken: data.sessionToken,
                    ExpiredTime: data.expiredTime
                });
            });
        }
    });


    document.getElementById("file-input").onchange = function () {
        var file = this.files[0];
        if (!file) return;

        var ary = file.name.split('.');
        var suffix = ary[ary.length - 1];

        // 分片上传文件
        cos.sliceUploadFile({
            Bucket: Bucket,
            Region: Region,
            Key: '/' + prefix + '-' + genFileName() + '.' + suffix,
            Body: file
        }, function (err, data) {
            console.log(err, data);
        });
    }

下面是后端返回的临时token

{
"tmpSecretId":"AKIDwT43Ky3bGZ6PtGfSRQTo1ndyT5W0m02i",
"tmpSecretKey":"eEOrOWTdZZpa5JAZtgXG3Pbn3w65XUUd",
"sessionToken":"394b3ba8b49778a6873dccc3e4411c921a72f74330001",
"expiredTime":1541944222
}

下面是上传报错

<?xml version='1.0' encoding='utf-8' ?>
<Error>
	<Code>AccessDenied</Code>
	<Message>Access Denied.</Message>
	<Resource>test-1258017396.cos.ap-beijing.myqcloud.com</Resource>
	<RequestId>NWJlODJmZDRfY2ZhZjJhMDlfNjUzY18xMGYwZjY0</RequestId>
	<TraceId>OGVmYzZiMmQzYjA2OWNhODk0NTRkMTBiOWVmMDAxODc0OWRkZjk0ZDM1NmI1M2E2MTRlY2MzZDhmNmI5MWI1OTBjYzE2MjAxN2M1MzJiOTdkZjMxMDVlYTZjN2FiMmI0NmE3MWMwY2E2MGQ2YjgwZjE4ZmQ1ZGRiOWVkZjU5Y2M=</TraceId>
</Error>

下面是后端代码

    @Value("${cos.secret.id}")
    private String secretId;

    @Value("${cos.secret.key}")
    private String secretKey;

    @Value("${cos.appId}")
    private String appId;

    private TempSecret tempSecret;

    public String getRegion() {
        return "ap-beijing";
    }

    public String getBucket() {
        return "test-123456";
    }
            
    public TempSecret generateSecret() {
        if (this.tempSecret != null && !this.tempSecret.isExpired()) {
            return this.tempSecret;
        }
        /* 如果是循环调用下面举例的接口,需要从此处开始您的循环语句。切记! */
        TreeMap<String, Object> config = new TreeMap<String, Object>();
        config.put("SecretId", secretId);
        config.put("SecretKey", secretKey);

        /* 请求方法类型 POST、GET */
        config.put("RequestMethod", "GET");

        /* 区域参数,可选: gz: 广州; sh: 上海; hk: 香港; ca: 北美; 等。 */
        config.put("DefaultRegion", getRegion());

        QcloudApiModuleCenter module = new QcloudApiModuleCenter(new Sts(), config);

        TreeMap<String, Object> params = new TreeMap<String, Object>();
        /* 将需要输入的参数都放入 params 里面,必选参数是必填的。 */
        /* DescribeInstances 接口的部分可选参数如下 */
        params.put("name", getBucket());

        /**
         * 策略文档
         * https://cloud.tencent.com/document/product/436/18023
         */
        //@formatter:off

        String policy ="{\"statement\":[{\"principal\":{\"qcs\":[\"qcs::cam::anyone:anyone\"]},\"effect\":\"allow\",\"action\":[\"name/cos:*\"],\"resource\":[\"qcs::cos:ap-beijing:uid/123456:test-123456/*\"]}],\"version\":\"2.0\"}";

        //@formatter:on
        params.put("policy", policy);

        /* 在这里指定所要用的签名算法,不指定默认为 HmacSHA1*/
        //params.put("SignatureMethod", "HmacSHA256");

        /* generateUrl 方法生成请求串, 可用于调试使用 */
        System.out.println(module.generateUrl("GetFederationToken", params));
        String result = null;
        try {
            /* call 方法正式向指定的接口名发送请求,并把请求参数 params 传入,返回即是接口的请求结果。 */
            result = module.call("GetFederationToken", params);

            logger.debug("获取“临时secret”成功," + result);

            this.tempSecret = new TempSecret(result);
        } catch (Exception e) {
            System.out.println("error..." + e.getMessage());
        }
        return this.tempSecret;
    }
用户3841112用户3841112提问于
郭宗翰回答于
用户1527075回答于
相柳

深圳市美奔科技有限公司 · 运维 (已认证)

源于信仰,始于爱好,格物,致知— www.8n8k.com,17603077568回答于

看下对应的 appid 这几个参数,还有存储桶在控制台的读写权限。

所属标签

可能回答问题的人

  • 云存储

    腾讯云 · 云存储 (已认证)

    16 粉丝0 提问0 回答
  • galenye

    腾讯 · 工程师 (已认证)

    5 粉丝0 提问38 回答
  • Jinqn

    腾讯 · 高级工程师 (已认证)

    19 粉丝0 提问60 回答
  • 腾讯云技术服务团队

    腾讯云 · 技术服务团队 (已认证)

    25 粉丝0 提问4 回答
  • 宝哥@devops运维

    腾讯 · 高级云计算工程师 (已认证)

    71 粉丝0 提问0 回答
  • elliswu

    腾讯计算机系统有限公司 · 高级工程师 (已认证)

    5 粉丝0 提问0 回答

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励