使用安全方式上传COS并通过事件回调通知的实践

移动端文件上传是现在互联网应用架构中很常见的一种场景,在该场景中,往往会涉及到以下几个问题。

1.移动端权限控制

2.移动端传输效率

3.数据安全性

4.弹性扩容

5.成本

6.数据处理

本文介绍的“使用安全方式上传COS并通过事件回调通知”能够很好的解决以上6个问题。下面咱们看看如何实现的。

整体方案架构图如下。这里会用到3个主要的腾讯云产品,

腾讯云访问管理(Cloud Access Management,CAM)

腾讯云对象存储(Cloud Object Storage,COS)

腾讯云无服务器云函数(Serverless Cloud Function,SCF)

安全访问COS和事件回调的业务架构图

步骤1:由客户端向应用服务器发起请求。用于获取STS临时账号。

移动端调用DEMO代码可以参考COS官方文档https://cloud.tencent.com/document/product/436/9068

PC端调用DEMO代码可以参考COS官方文档https://cloud.tencent.com/document/product/436/9067

Q:这里需要通过中间的应用服务器来获取临时账号,为什么不用主账号和子帐号?

A:

  • 主账号权限过大,可无限制操作所有的资源,非常不适合保存在客户端,有安全隐患。
  • 子帐号虽然可以通过策略授权来限制权限范围。但如果保存到客户端后,不同的客户操作行为和资源不容易隔离,同时也没有时间控制,也不适合保存在客户端。

步骤2:应用服务器(Server端)接到客户端请求后,使用子帐号密钥向CAM服务发起临时账号申请。

Server端需要提供接口,用于客户端发起临时账号获取请求。而server端相对来说安全级别更高,可部署子帐号ID和密钥。子帐号默认具有STS获取权限

多种语言(包括java,nodejs,php,python)获取STS的示例可参考

https://github.com/tencentyun/qcloud-cos-sts-sdk

需要注意的是,在申请STS时,我们需要赋予临时账号一定的权限,用于后续客户端操作COS来使用,例如我们这里设置的policy是

{
    "statement": [{
        "action": ["name/cos:GetObject", "name/cos:PutObject"],
        "effect": "allow",
        "resource": ["qcs::cos:ap-beijing:uid/1251956900:prefix//1251956900/sunweitest/*"]
    }],
    "version": "2.0"
}

拆分说明

action为“操作行为”,示例中包括了GetObject,PutObject,表示可以单文件下载对象和单文件上传对象。

更多COS API,请参考https://cloud.tencent.com/document/product/436/7751

effect为“效力”,示例中allow为允许行为,参数可选 ("allow" | "deny")

resource为“资源”

qcs:project_id:service_type:region:account:resource
  • qcs:是 qcloud service 的简称,表示是腾讯云的云资源。该字段是必填项。
  • project_id:描述项目信息,仅兼容 CAM 早期逻辑。当前策略语法禁止填写该信息。
  • service_type:描述产品简称,如 CVM、CDN 等,产品的检测具体细节请参考对应的产品文档。值为*的时候表示所有产品。该字段是必填项。
  • region:描述地域信息。值为空的时候表示所有地域。腾讯云新版地域统一命名方式请参考 地域和可用区。腾讯云现有的地域命名方式定义如下:
  • account:描述资源拥有者的根账号信息。目前支持两种方式描述资源拥有者,uin 和 uid 方式。
  • resource:描述各产品的具体资源详情。

示例中resource的含义就是,region资源为COS产品的北京园区,uid为1251956900,目录前缀为1251956900/sunweitest/ 下的所有资源。

policy的完整含义是允许COS产品北京园区_UID为1251956900下且bucket为sunweitest所有资源进行GetObjectPutObject_操作。

更详细的策略说明,请参考文档https://cloud.tencent.com/document/product/598/10603

步骤3:STS颁发临时账号ID,临时密钥,临时token。

调用请求示例:

https://sts.api.qcloud.com/v2/index.php?Action=GetFederationToken&Nonce=323820010&Region=gz&RequestClient=SDK_JAVA_1.3&SecretId=AKIDjNskW7UnqiO3aSLm9KKD0b1Rr8DQIP8k&Signature=zglPT6XJMkl1qzbcfNGUq48wFr0=&Timestamp=1558577532&name=1251956900&policy={"statement": [{"action": ["name/cos:GetObject","name/cos:PutObject"],"effect": "allow","resource":["qcs::cos:ap-beijing:uid/1251956900:prefix//1251956900/sunweitest/*"]}],"version": "2.0"}

STS返回成功示例:

{
    "codeDesc": "Success",
    "code": 0,
    "data": {
        "credentials": {
            "tmpSecretId": "AKIDlFH1MtbCKv3pGzDoS5IYEMfoeCzk2vLD",
            "tmpSecretKey": "BO04DXHPFjj4CKNSy2ECFSPrKm7M7anz",
            "sessionToken": "5638d26115438d38e9137f5dfeceea2e9718431f30001"
        },
        "expiredTime": 1558579344
    },
    "message": ""
}

步骤4:应用服务器将临时账号ID,临时密钥,临时token等信息返给客户端

tmpSecretId:临时账号ID

tmpSecretKey:临时账号密钥

sessionToken:临时账号token

expiredTime:临时账号过期时间

备注:expiredTime过期或tmpSecretId错误会返回

The Access Key Id you provided does not exist in our records (Status Code: 403; Error Code: InvalidAccessKeyId)

步骤5:客户端使用临时账号ID,临时密钥,临时token向COS发起操作请求。

这里所做的操作权限,是和之前步骤2中设置的policy相关的。

我们这里用临时账号模拟做三个请求,分别是putobject,getobject,headobject。可以看到前两个可以执行,第三个报403无权限。符合预期。

临时账号模拟COS操作请求

步骤6:SCF监听COS的操作事件,符合条件则触发事件。

登录SCF控制台 https://console.cloud.tencent.com/scf

创建函数,例如创建一个php5的空白模板

创建SCF函数

示例函数代码如下

<?php
    $gl = 1;
    function main_handler($event, $context) {
        $url1='http://xxxxxx.com/api?a=1&b=2';
        //应用服务器调用入口        
        curl_file_get_contents($url1);
        return "200 ok";
    }
       /*
        *  php访问url路径,get请求
        */
    function curl_file_get_contents($durl){       
        // 初始化
        $curl = curl_init();
        // 设置url路径
        curl_setopt($curl, CURLOPT_URL, $durl);
        // 将 curl_exec()获取的信息以文件流的形式返回,而不是直接输出。
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true) ;
        // 在启用 CURLOPT_RETURNTRANSFER 时候将获取数据返回
        curl_setopt($curl, CURLOPT_BINARYTRANSFER, true) ;
        // 执行
        $data = curl_exec($curl);
        // 打印请求头信息
            echo curl_getinfo($curl, CURLINFO_HEADER_OUT);
        // 关闭连接
        curl_close($curl);
        // 返回数据
        return $data;
    }
?>

触发器设置,以下是可以触发COS事件的列表,值得注意的是,这里的触发时间都是操作事件完成后的触发,所以如果要对文件做处理,不用担心客户端操作时间差的问题。

SCF事件触发列表

步骤7:根据预先写好的事件处理程序,进行自定义业务处理,并将结果发送给应用服务器端。

触发事件后,验证是否成功。

SCF运行日志

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券