时间: 2020-09-03 00:08:26 人气: 2332 评论: 0
移动端文件上传是现在互联网应用架构中很常见的一种场景,在该场景中,往往会涉及到以下几个问题。
1.移动端权限控制
2.移动端传输效率
3.数据安全性
4.弹性扩容
5.成本
6.数据处理
本文介绍的“使用安全方式上传COS并通过事件回调通知”能够很好的解决以上6个问题。下面咱们看看如何实现的。
整体方案架构图如下。这里会用到3个主要的腾讯云产品,
腾讯云访问管理(Cloud Access Management,CAM)
腾讯云对象存储(Cloud Object Storage,COS)
腾讯云无服务器云函数(Serverless Cloud Function,SCF)
步骤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
*的时候表示所有产品。该字段是必填项。示例中resource的含义就是,region资源为COS产品的北京园区,uid为1251956900,目录前缀为1251956900/sunweitest/ 下的所有资源。
policy的完整含义是允许对COS产品北京园区_UID为1251956900下且bucket为sunweitest的所有资源进行GetObject和PutObject_操作。
更详细的策略说明,请参考文档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无权限。符合预期。
步骤6:SCF监听COS的操作事件,符合条件则触发事件。
登录SCF控制台 https://console.cloud.tencent.com/scf
创建函数,例如创建一个php5的空白模板
示例函数代码如下
<?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事件的列表,值得注意的是,这里的触发时间都是操作事件完成后的触发,所以如果要对文件做处理,不用担心客户端操作时间差的问题。
步骤7:根据预先写好的事件处理程序,进行自定义业务处理,并将结果发送给应用服务器端。
触发事件后,验证是否成功。