回调通知是指客户端在上传时指定服务端在处理完上传请求后,应该通知某个特定服务器,在该服务器确认接收了该回调后才将所有结果返回给客户端。

因为加入了回调请求和响应的过程,相比简单上传,使用回调通知机制一般会导致客户端花费更多的等待时间。

开发者可以要求七牛云存储在某文件上传完成后向特定的 URL 发起一个回调请求。七牛云存储会将该回调的响应内容作为文件上传响应的一部分一并返回给客户端。回调的流程如下:

要启用回调功能,业务服务器在签发上传凭证时需要设置上传策略 (PutPolicy)中的 callbackUrl 和 callbackBody 字段。

回调地址

通过设定上传策略中的 callbackUrl 字段为一个有效的地址,即可让七牛云存储在文件上传完成后向该地址发起回调请求。该地址可以是一个 HTTP 或者 HTTPS 的 URL,允许公网访问。

如果需要传递自定义的请求内容,开发者可以考虑配合使用上传策略中的 callbackBody 字段。如果只有 callbackUrl 而没有 callbackBody,回调服务器收到的请求内容将为空。

回调内容

同普通客户端直传和重定向上传一样,用户也可以控制回调中传递到客户回调服务器的反馈信息。callbackBody 的格式如下:

=(|)[&=(|)...]

一个典型的 callbackBody 设置如下(内容经过格式化方便阅读):

put_policy = '{

...

"callbackBody" : "name=$(fname)&

hash=$(etag)&

location=$(x:location)&

price=$(x:price)&

uid=123"

...

}'

上面的 callbackBody 示例中,混合使用了魔法变量 name、hash,自定义变量 location、price 及自定义常量 uid。

假设应用客户端发出了如下的上传请求:

其中,客户端发送了自定义变量的值 x:location = Shanghai 和 x:price = 1500.00,七牛云存储将根据上传资源的实际情况填写魔法变量 $(fname) 和 $(etag) 的值。

完成上传后,七牛云存储便会构造出如下的回调信息(内容经过格式化方便阅读):

name=sunflower.jpg&

hash=Fn6qeQi4VDLQ347NiRm- \

RlQx_4O2&

location=Shanghai&

price=1500.00&

uid=123

七牛云存储将这组数据作为请求 Body 发送至用户指定的回调服务器,请求方式为 POST。回调服务器将接收到以下格式的请求内容:

POST /callback HTTP/1.1

Content-Type: application/x-www-form-urlencoded

User-Agent: qiniu go-sdk v6.0.0

Host: api.examples.com

Authorization: QBox iN7NgwM31j4-BZacMjPrOQBs34UG1maYCAQmhdCV:tDK-3f5xF3SJYEAwsll5g=

name=sunflower.jpg&hash=Fn6qeQi4VDLQ347NiRm- \

RlQx_4O2&location=Shanghai&price=1500.00&uid=123

回调服务器接收到回调请求后,负责生成七牛返回给客户端的数据(json 格式),该数据作为此次回调请求的响应内容。如果回调成功,回调服务应对七牛云存储作出类似如下的响应(**注意:**回调响应内容由回调服务器生成,以下仅为示例):

HTTP/1.1 200 OK

Server: nginx/1.1.19

Date: Thu, 19 Dec 2013 06:27:30 GMT

Content-Type: text/html

Transfer-Encoding: chunked

Connection: keep-alive

Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0

Pragma: no-cache

{"success":true,"name":"sunflowerb.jpg"}

七牛云存储将上面的回调结果返回给客户端,客户端接收到以下响应:

HTTP/1.1 200 OK

Content-Type: application/json

Cache-Control: no-store

Server: nginx/1.4.4

Date: Thu, 19 Dec 2013 08:04:56 GMT

Pragma: no-cache

X-Log: BDT:4;BDT:2;LBD:13;rs.put:1048;rs-upload.putFile:2514;UP.CB:3088;UP:5603

X-Reqid: iDYAAPBicOGXLUET

{"success":true,"name":"sunflowerb.jpg"}

如果回调失败,客户端会收到 HTTP 错误码 579,详细的错误信息在 Body 部分给出,如下所示(内容经过格式化方便阅读):

{

"error":"{

"callback_url":"",

"callback_bodyType":"",

"callback_body":"",

"token":"",

"err_code":,

"error":"",

"hash":"Fn6qeQi4VDLQ347NiRm-RlQx_4O2",

"key":"sunflower.jpg"

}"

}

如果回调服务器返回如下所示的 Json 格式的错误内容:

{

"error":""

}

并且设置 Content-Type 为 application/json,则业务端能解析出 并填入 字段返回给客户端。错误信息需要是String格式,建议可以是query的方式,如code=400&message=‘no hedaer’

安全性

由于回调地址是公网可任意访问的,那如何确认回调是合法的呢?

七牛云存储在回调时会对请求数据签名,并将结果包含在请求头 Authorization 字段中,示例如下:

Authorization:QBox iN7NgwM31j4-BZacMjPrOQBs34UG1maYCAQmhdCV:tDK-3f5xF3SJYEAwsll5g=

其中 QBox 为固定值,iN7Ngw…dCV 为用户的 Accesskey,tDK-3f…5g= 为签名结果 encoded_data。

回调服务器可以通过以下方法验证其合法性:

获取 Authorization 字段中的签名结果 encoded_data

根据 Accesskey 选取正确的 SecretKey

获取明文 data = Request.URL.Path +"\n" +Request.Body,部分语言或框架无法直接获取请求 body 的原始数据,在自行拼接时应当注意,body 中的数据是经过URL 安全的 Base64 编码的。

采用 HMAC-SHA1 签名算法,对明文 data 签名,密钥为 SecretKey,比较签名结果是否与 Authorization 字段中的 encoded_data 字段相同,如相同则表明这是一个合法的回调请求。

注意:业务端服务器回调鉴权的Content-Type类型应该与上传策略中指定的callbackBodyType相同,默认为 application/x-www-form-urlencoded,当 Content-Type 为 application/x-www-form-urlencoded 时,签名内容必须包括请求内容。当 Content-Type 为 application/json 时,签名内容不包括请求内容。签名方式可参考 Authorization

以 PHP 语言为例,验证代码如下:

/**

require_once __DIR__ . '/../autoload.php';

use Qiniu\Auth;

$accessKey = getenv('QINIU_ACCESS_KEY');

$secretKey = getenv('QINIU_SECRET_KEY');

$bucket = getenv('QINIU_TEST_BUCKET');

$auth = new Auth($accessKey, $secretKey);

//获取回调的body信息

$callbackBody = file_get_contents('php://input');

//回调的contentType

$contentType = 'application/x-www-form-urlencoded';

//回调的签名信息,可以验证该回调是否来自七牛

$authorization = $_SERVER['HTTP_AUTHORIZATION'];

//七牛回调的url,具体可以参考:http://developer.qiniu.com/docs/v6/api/reference/security/put-policy.html

$url = 'http://172.30.251.210/upload_verify_callback.php';

$isQiniuCallback = $auth->verifyCallback($contentType, $authorization, $url, $callbackBody);

if ($isQiniuCallback) {

$resp = array('ret' => 'success');

} else {

$resp = array('ret' => 'failed');

}

echo json_encode($resp);

**注意:**如果回调数据有用户的敏感数据,建议回调地址使用 HTTPS 协议。

七牛云php回调,回调通知_开发指南_对象存储 - 七牛开发者中心相关推荐

  1. 物联卡查询流量_物联卡流量查询_python_API文档_开发指南_物联网无线连接服务 - 阿里云...

    物联网卡流量查询接口 步骤 1 创建阿里云账号 为了访问服务,您需要有一个阿里云账号.如果没有,可首先按照如下步骤创建阿里云账号: 访问阿里云 官方网站,单击页面上的 免费注册 按钮. 按照屏幕提示完 ...

  2. python 监听tcp端口_创建TCP监听_创建TCP监听_功能示例_Python SDK示例_SDK 参考_开发指南_负载均衡 - 阿里云...

    # encoding=utf-8 import json import sys # 调用AcsClient参数进行身份验证 from aliyunsdkcore.client import AcsCl ...

  3. web开发指南_成为专业Web开发人员的实用指南

    web开发指南 This article is meant to serve as a practical guide to becoming a professional web developer ...

  4. OSS对象存储——七牛云存储

    七牛云存储 需求: 项目中用户头像.文章图片等数据需要使用文件存储系统来保存. 方案: 自己搭建文件系统服务 选用第三方对象存储服务 七牛云 http://www.qiniu.com 使用 CDN 使 ...

  5. extjs 实用开发指南_如何提出有效问题:针对开发人员的实用指南

    extjs 实用开发指南 Learning is a journey that never ends. At every point in your career, you will keep lea ...

  6. 区块链开发指南_区块链开发权威指南

    区块链开发指南 by Haseeb Qureshi 由Haseeb Qureshi 区块链开发权威指南 (The authoritative guide to blockchain developme ...

  7. libgdx开发指南_使用libgdx进行Android游戏开发–一天中的原型,第1a部分

    libgdx开发指南 在本文中,我将绕开游戏引擎和组件的构建模块,并演示如何使用libgdx库快速制作游戏原型. 您将学到什么: 创建一个非常简单的2D Shooter Platformer游戏. 完 ...

  8. python和pygame游戏开发指南_学习记录

    <python和pygame游戏开发指南> Making Games With Python and Palme [美]Ai Sweigart 著,李强 译,2015.12第一版 文章目录 ...

  9. java oss 批量传输_阿里云OSS对象存储,服务端签名后直传阿里云OSS

    继续上一章文章,这次要操作的是,浏览器请求服务要到签名后直传给OSS对象存储. 1.写好服务端的方法,传给前台相应的密钥 @Resource OSSClient ossClient; @Value(& ...

最新文章

  1. ng-template、ng-container、ng-content和ngTemplateOutlet、ngProjectAs傻傻分不清!他们究竟是干啥的???
  2. Sass在编译中文注释中报错
  3. 做一个更好的A牌 从《Artifact》2.0看Valve的设计思路
  4. Psych101(part7)--Day7
  5. 1031. 查验身份证(15)
  6. cgroups(7)— Linux中文手册页
  7. SpringBoot 使用Class.forName方法返回java.lang.ClassNotFoundException
  8. kubernetes视频教程笔记 (22)-存储-Secret
  9. 【渝粤题库】国家开放大学2021春2251团体工作题目
  10. VS2019 配色_新手设计师如何做好设计配色
  11. OSChina 周五乱弹 —— 毁人不倦的大师们
  12. Qt:QPushButton 单击、双击响应区分
  13. 当你发现微信好友朋友圈是“一条杠”,你会把她、他删除吗?
  14. 学习如何合理的配置服务器
  15. 二维彩虹产品功能更新(H5编辑二维码)
  16. jquery如何根据id获取标签内的值,以及如何通过id赋值
  17. sudo: unable to resolove host iZ2ze7gg2o6tplktzc1le0Z问题的解决方法
  18. html转换为pdf c#,wkhtmltopdf - 直接在C#中将html代码转换为pdf
  19. 2019一键清空朋友圈_批量清理朋友圈说说
  20. pixhawk2.4.8(FMUV3)变砖拯救方法

热门文章

  1. JAVA毕业设计淮安城市开放大学实习实训管理系统计算机源码+lw文档+系统+调试部署+数据库
  2. word 2013 新建批注 显示/隐藏批注 删除批注
  3. Html静态页面缓存问题,解决缓存更新不及时需清空缓存更新页面
  4. html内嵌子页面并配合CGI进行页面更新
  5. 【跨端应用】—— uniapp黑马商城App学习笔记(二)
  6. AR体感互动产品大合集
  7. Python open()方法中的newLine参数
  8. 生日快乐程序_时光匆匆,爱你不变——祝星广十七岁生日快乐
  9. 在python中、int表示的数据类型是_python--002--数据类型(int、str)
  10. 路由器的两种工作模式