轻应用开发指南
(→Web版和H5版的区分) |
|||
第143行: | 第143行: | ||
应用目前可以通过浏览器的 userAgent 来区分,当前是显示在 Web 浏览器还是微博客户端中,这也是目前唯一的方式。 | 应用目前可以通过浏览器的 userAgent 来区分,当前是显示在 Web 浏览器还是微博客户端中,这也是目前唯一的方式。 | ||
+ | 另外需要注意的是,通过LinkCard方式接入的第三方内页 | ||
===Web 版 JavaScript 包的使用=== | ===Web 版 JavaScript 包的使用=== |
2014年5月26日 (一) 01:36的版本
轻应用开发其实并不复杂,就是如何处理微博框架传递过去的参数,并做相应的处理。
目录 |
接收框架参数
应用框架会通过 POST 形式,发送给第三方页面一个加密后的参数 signed_request, 参数中包含了 uid、access_token 等信息,如果应用需要用到,就需要解密后才能使用。
如果是纯展示类应用,可以不用理会这个参数。
有一点需要特别注意,就是参数 signed_request 是 POST 方式传输的,第三方的页面如果不支持 POST 接收,可能会无法正确显示。
signed_request 的加密方式
signed_request 用小数点分隔成两段,小数点前是校验数据,小数点后是真实数据。 校验数据用于确保数据的有效性,比如没有被篡改过,只有校验成功的真实数据,才是可信的。
这二者都使用了 base64 编码,因此需要先进行数据还原。base64 数据的部分字符在 HTTP 传输的过程中可能会被和 URL 中其他字符混淆,因此开发者拿到的 base64 字符串,都做了特殊处理。因此 base64 解码之前,需要先将字符串还原为标准的 base64 字符。
还原方式:先根据字符串长度补上相应长度的等号(补上等号后的字符串长度应该是 4 的整数倍),然后将其中所有的 - 替换成 +,所有 _ 替换成 /。
真实数据 base64 解码后,转成 JSON 对象,就是开发者需要的信息了,下文会详细介绍每个参数。
如何使用校验数据?
首先,检查真实数据 base64 解码后 JSON 中的 algorithm,必须是 HMAC-SHA256。
其次,通过校验数据进行校验,校验方法如下:
- 校验数据 base64 解码后(可能是乱码的字符,不用管它),保存在变量里,用于后续对比。
- 对 base64 解码之前的数据,使用应用的 app secret 进行 sha256 加密,加密后的数据和校验数据 base64 解码后的结果必须一致,才能保证数据的有效性。
因此,signed_request 的解密方法已经可以写出来了。
使用 SDK 进行数据解密
微博开放平台的众多 SDK 中,PHPSDK 和 JavaSDK 已经内置了 signed_request 解码功能,可以直接使用。其他语言需要开发者自行完成。
使用 PHPSDK 从 signed_request 提取参数
if(!empty($_POST["signed_request"])){ $o = new SaeTOAuth( WB_AKEY , WB_SKEY ); $data = $o->parseSignedRequest($_REQUEST["signed_request"]); if($data == '-2'){ die('sign is error!'); } else { $_SESSION['oauth2'] = $data; } }
PHPSDK 解密 signed_request 的方法如下,供其他语言参考
/** * 解析 signed_request * @param string $signed_request 应用框架在加载iframe时会通过向Canvas URL post的参数signed_request * @return array */ function parseSignedRequest($signed_request) { // 将 $signed_request 参数,用小数点.分隔成数组,下标0的赋值给 $encoded_sig,下标1的复制给 $payload list($encoded_sig, $payload) = explode('.', $signed_request, 2); // 对 $encoded_sig 进行 base64 解码,然后赋值给 $sig $sig = self::base64decode($encoded_sig); // 对 $payload 进行 base64 解码,并将字符串转为 JSON 赋值给 $data $data = json_decode(self::base64decode($payload), true); // 如果 $data 中的 algorithm 不是 HMAC-SHA256,表示数据校验出错,直接返回 -1 if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') return '-1'; // 使用 app secret 对 $payload 进行 sha256 加密 $expected_sig = hash_hmac('sha256', $payload, $this->client_secret, true); // 如果 sha256 加密后的结果和 $sig 是一致的,那么 $data 数据就没问题,直接返回给调用方;否则>表示数据校验出错,返回 -2 return ($sig !== $expected_sig)? '-2' : $data; } /** * @ignore */ function base64decode($str) { // 将需要 base64 解码的字符串,按照字符串长度先补上相应的等号(补上等号后的字符串长度应该是4>的整数倍),然后将其中的 - 和 _ 分别替换成 + 和 /,然后对处理后的字符串执行 base64 解码 return base64_decode(strtr($str.str_repeat('=', (4 - strlen($str) % 4)), '-_', '+/')); }
signed_request 解密后的格式
未登录状态访问应用参数
参数名 | 必选 | 类型 | 说明 |
---|---|---|---|
user | true | array | 当前用户对象 |
algorithm | true | string | 签名算法,暂时用HMAC-SHA256 |
issued_at | true | int | 服务端生成时间, unix timestamp格式 |
referer | true | string | 页面的 document.referrer |
ouid | false | uint64 | 当前应用的安装者 uid,站内应用无此参数 |
登录状态访问应用,自动授权成功参数
参数名 | 必选 | 类型 | 说明 |
---|---|---|---|
user | true | array | 当前用户对象 |
algorithm | true | string | 签名算法,暂时用HMAC-SHA256 |
issued_at | true | int | 服务端生成时间, unix timestamp格式 |
expires | true | int | access_token 过期时间,unix timestamp 格式 |
oauth_token | true | string | access_token |
user_id | true | unit64 | 当前登录用户微博 user id |
referer | true | string | 页面的 document.referrer |
scope | true | string | 应用的 scope 参数 |
ext_data | true | string | 扩展字段,暂时用不上 |
ouid | false | uint64 | 当前应用的安装者 uid,站内应用无此参数 |
能正确接收参数以后,应用还需要区分当前所处的平台。
Web版和H5版的区分
应用的基本信息中,可以选择 Web 版或者 H5 版之一,或者二者都兼容。如果二者都兼容,就有必要区分 Web 版和 H5 版。
区分的作用有两个:一是为了让不同的设备下,应用可以进行适配,以达到最佳的显示效果;二是,Web 版和 H5 版调用的 Javascript 包不一样,区分后,可以减少不必要的 JS 代码。
应用目前可以通过浏览器的 userAgent 来区分,当前是显示在 Web 浏览器还是微博客户端中,这也是目前唯一的方式。
另外需要注意的是,通过LinkCard方式接入的第三方内页
Web 版 JavaScript 包的使用
Web 版是通过 iframe 来嵌入第三方应用,除了接收框架 POST 的参数,还需要和框架进行通讯,比如:iframe 高度自适应、获取父页面的信息、唤起登录浮层等。
这些都是通过框架提供的一个 JavaScript 文件来提供的,具体使用方法请阅读 Web 版 Javascript 包使用文档。
H5 版如何调用微博客户端的 JS API
微博客户端自从 4.3.0 开始,在 Webview 中新增了 JS API 功能,方便网页应用通过 JS API 调用一些系统功能,例如:获取网络状态、定位信息、扫描二维码、查看大图等功能。
详细试用方法,请阅读:微博客户端 JS API 使用文档
如何唤起微博支付
目前微博支付只支持线下接入,需要接入的开发者,请联系 chenlei6@staff.sina.com.cn。
如何接入 linkcard 解析
什么是 LinkCard
一条微博中如果包含一个链接,将展将现为一个短链接,如图:
如果连该链接被解析为包含一个对象数据的特殊短链,那么该对象数据就可以在微博消息流内以卡片形式显示。这种形态就是微博
消息流 LinkCard(链接卡片)解析。
被解析的链接会被替换为miniCard,显示上更丰富有力,点击率更高。在微博正文的下面,一般会解析出LinkCard,可以展示出缩略图、标题、简介等信息。解析效果如图:
LinkCard 是第三方网站链接在微博上承载特定功能的必要形式,依赖 LinkCard,可以实现视频链接的直接播放、音频链接的直接试听等效果,以及 Page 轻应用直接载入。
在用户分享第三方网站的链接到微博上时,我们将通过链接特征,识别出该链接是否属于某个 Page 轻应用接入方。对于 Page 轻应用接入方的链接,我们将调用该接入方登记的解析回调接口,获取事先约定好格式的对象数据。这些能成功获取到对象数据的链接,就可以在pc端、移动客户端展示成 LinkCard,并实现用户点击后可以完成轻应用框架的加载。
优点:接入方只需按标准、规范的流程开发回调接口即可实现快速接入。
缺点:接入方属于被动接入,回调接口有失败率,可能造成个别链接LinkCard解析不成功。
如何接入 LinkCard?
线下提交申请,联系 mingjin@staff.sina.com.cn。
接入 LinkCard 接入方需要做的事情
我们先看看 LinkCard 的工作流程:
图中的 1、2 具体描述如下:
1、接入方提供解析长 URL 匹配规则
长 URL 匹配规则是一个简单的正则表达式,匹配上的长 URL 在转短链时会当做参数用来调用接入方的对象数据回调接口,即图中的链接域名等特征。
例如,我们要解析某商品为 LinkCard,则商品的长链接 URL 是:http://www.productmall.com/sample/256819,那么长 URL 匹配规则应该是:www.productmall.com/sample/。(请注意,http:// 不包含,可变的商品编号也没有包含在内)
2、接入方提供解析对象数据回调接口
该接口由接入方来开发。微博平台在通过上面的长 URL 匹配规则,匹配上的长 URL 在转短链时会调用接入方的这个接口,参数为匹配上的长 URL。
接入方判断参数 URL 为一个正确的需要解析为 LinkCard 的页面时,接口返回需要解析的对象数据,理论上不同的参数 URL 返回不同的对象数据。反之,接口返回错误,微博平台将认为这个链接不是正常的 LinkCard 对象,转为普通短链,不做 LinkCard 解析。
对象数据接口
接口请求方式:GET 接口参数:url,符合匹配规则的长 URL 接口返回值:JSON, JSON数据的具体属性字段见下表:
属性 | 属性类型 | 是否必填 | 说明描述 |
---|---|---|---|
display_name | string | 必填 | LinkCard 显示的名称 |
id | string | 选填 | LinkCard的标识id。当有接入官方客户端二维码唤起功能时,先申请域名id 后填写该字段,值形式为123456:abcdefg。其中123456为向平台申请后分配的域id,各接入方均不相同。abcdefg为接入方自己补充的标识字符串,10-50 位,可含英文、数字、下划线,需同下文的URL一一对应。二者用英文冒号分隔。 |
image | media link | 必填 | LinkCard的缩略显示图片,图片大小强烈建议为120×120像素,为一个media link类型的对象。 |
summary | string | 选填 | LinkCard的文字描述,字数建议控制在300字以内,建议填写。 |
url | string | 必填 | LinkCard的URL地址,该地址必须为一个纯净的URL,尽量不带有无关的参数,其将作为对象数据的唯一标识依据,保持该URL的干净将有利于赞数据的统一和有效。如果接入方填写了上文的id,则URL需同上文的id 一一对应。 |
tags | object array | 选填 | 标签属性,对象数据的通用属性,为一个object array的对象数组。 |
create_at | data time | 选填 | 创建时间,格式强烈建议用国际化格式:Wed Jan 06 11: 26: 01+0800 2010,或者用简易格式:2012-10-18。 |
object_type | string | 必填 | 对象类型,如商品为product。具体由平台同接入方约定。 |
上面的属性中,类型为 object、object array、media link 的,都是包含下一级属性的,具体说明如下:
image(media link)
属性 | 属性类型 | 是否必填 | 说明描述 |
---|---|---|---|
url | string | 必填 | 媒体的地址,本案例中,一级的image属性下应为LinkCard配图地址。 |
width | int | 选填 | 媒体的宽度,本案例中,一级的image属性下应为LinkCard配图的宽,建议为120像素 |
height | int | 选填 | 媒体的高度,本案例中,一级的image属性下应为LinkCard配图的高,建议为120像素 |
tags(object array)
属性 | 属性类型 | 是否必填 | 说明描述 |
---|---|---|---|
display_name | string | 必填 | 标签显示的名称 |
例如:
接入方提供的长URL匹配规则:www.productmall.com/sample/
示例链接:http://www.productmall.com/sample/256819
接入方提供的对象数据回调接口:http://www.productmall.com/api/get_data?url=
则我们的调用实例将为: http://www.productmall.com/api/get_data?url=http%3a%2f%2fwww.productmall.com%2fsampl e%2f256819
接入方返回数据如下:
(1)不接入官方客户端二维码唤起功能
{ "display_name": "这是商品的标题", "image": { "url": "http://www.productmall.com/7272.jpg", "width": 120, "height": 120 }, "summary": "这是商品的简介", "url": "http://www.productmall.com/sample/256819.html", "tags": [ { "display_name": "标签1" } ], "create_at": "2012-10-18", "object_type": "product" }
(2)接入官方客户端二维码唤起功能(假如接入方申请后,开放平台给接入方分配的域名 id 为1456439003)
{ "display_name": "这是商品的标题", "id": "1456439003:www_productmall_com_sample_256819", "image": { "url": "http://www.productmall.com/7272.jpg", "width": 120, "height": 120 }, "summary": "这是商品的简介", "url": "http://www.productmall.com/sample/256819.html", "tags": [ { "display_name": "标签1" } ], "create_at": "2012-10-18", "object_type": "product" }