青云应用需要服务提供商提供服务网页,整合到青云的 iframe 里面供用户使用。加载 iframe 时,用户授权信息会发送到对应的网址。服务提供商拿到授权信息就可以通过青云 api 获取用户资源信息,为用户提供各种服务。
首先,服务提供商需要提供一个青云应用,以 URL 的形式整合到青云。我们建了一个 非常基础的青云应用示例程序 。 它使用 Django 提供 web 服务,结合 QingCloud Python SDK 与青云平台交互。您可以把示例程序同步到本地,用python运行:
$ # install dependence
$ sudo apt-get install python-pip apache2 git
$ sudo pip install Django qingcloud-sdk
$ git clone https://github.com/yunify/sample_qc_ap.git
$ cd sample_qc_ap/mysite
$ python manage.py runserver 127.0.0.1:8080
Performing system checks...
System check identified no issues (0 silenced).
January 29, 2015 - 02:50:11
Django version 1.7.4, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8080/
Quit the server with CONTROL-C.
这样您本地就运行了一个示例应用,您可以通过浏览器访问 http://127.0.0.1:8080/ 。
注解
由于青云应用必须使用 HTTPS 协议,要在青云应用平台运行示例程序,需要提供 HTTPS URL 。这里提供两个方法,您可以任选一个:
用户,青云和服务提供商三方互相机制
具体使用场景如下
当用户进入应用时,会通过浏览器 post form 到青云应用 URL , 包含 payload 和 signature 两个域,编码方式如下:
注解
编码参考自 Base64 URL_applications
这里提供 php 和 python 的编码/解码函数供开发者参考:
#php版本
function base64_URL_encode($data) {
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
function base64_URL_decode($data) {
return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT));
}
#python版本
import base64
def base64_URL_decode(inp):
return base64.urlsafe_b64decode(str(inp + '=' * (4 - len(inp) % 4)))
def base64_URL_encode(inp):
return base64.urlsafe_b64encode(str(inp)).rstrip('=')
青云应用拿到请求后,首先要验证请求是否来自青云, 对拿到的 payload 按 HmacSHA256 签名,并 base64 URL 编码。 得到的字符串应与 signature 值相同。可参考 python sdk 中对应的代码
def extract_payload(self, payload, signature):
expected_sig = self.sign_string(payload)
if signature != expected_sig:
return None
return json_load(base64_URL_decode(payload))
其中 sign_string 调用 python 提供的 sha256 对 payload 签名, 具体步骤请参考 sdk 对应代码。payload 解码后得到 json 对象,包含 user_id, access_token, action, zone, expires 和 lang 等信息, 例如:
{
"user_id": "usr-inea9w7Z",
"access_token": "t1aPdMq0yOkfhtdut9MnCUydEtSfJ1kg",
"action": "view_app", # 表示用户进入应用
"zone": "pek2",
"expires": "2014-02-08T12:00:00.000Z",
"lang": "zh_CN"
}
注解
上面的 action 除了进入应用( view_app )外,还有安装应用、卸载应用等事件通知, 详见 事件通知
需要提一下的是,由于请求来自青云,青云应用通常需要解除跨域的限制。 在示例代码中 , 使用Django提供的 “csrf_exempt” 解除跨域 post 限制。由于 Django 默认对 iframe 嵌入有限制,还需要使用 “xframe_options_exempt” 解除限制。
# allow post from other site
@csrf_exempt
# allow embedded into iframe
@xframe_options_exempt
def index(request):
...
示例代码中, “index” 函数处理 http://127.0.0.1:8080/sample/ 请求。当用户浏览器post授权信息到青云应用时会被调用。 index 函数参数是 request 对象,包含用户发过来的 form 域:
payload = request.POST["payload"]
signature = request.POST["signature"]
auth.extract_payload 是 sdk 提供的函数,用来验证 signature 和解码 payload 。 如果验证失败,返回 None ;成功的话,返回一个 dict 对象,包含 user_id, access_token, action, zone, expires 和 lang。 验证和解码具体方法在本节最开始已经介绍过,可以参照 sdk 相关代码。下面代码是调用 sdk 的场景:
from qingcloud.conn.auth import AppSignatureAuthHandler
....
auth = AppSignatureAuthHandler(settings.APP_ID,
settings.SECRET_APP_KEY)
access_info = auth.extract_payload(payload, signature)
if not access_info:
raise AuthException("Incorrect signature")
注解
APP_ID和SECRET_APP_KEY在青云开发者视图提交应用后就能拿到。
对于已有用户管理系统的应用,通常需要在用户第一次访问时,自动为青云用户注册账号。由于青云账号分主账户和子账户两种,这两个账号之间虽然共用一个登录邮箱,但是资源互相隔离,不宜通过账户邮箱直接注册。我们推荐的方式如下:
上述通知邮箱和手机号可以通过调用 describe_users 接口查询,下一节会以此为例,介绍如何调用青云API。
上一节介绍了青云应用如何得到用户浏览器发过来的授权信息,这一节介绍如何使用access_token访问青云api。
青云为服务提供商提供了专用的api频道: https://api.qingcloud.com/app/
这个频道除了提供 IAAS API 所有功能和扩展函数以外,还接受access_token,让服务提供商以用户身份调用api。而且新的频道兼容传统api的签名编码方式和 app的base64 URL编码方式 。
在示例应用里面,调用了 describe_users 函数获得当前用户的信息:
class QcControl:
def __init__(self, payload, signature):
...
self.conn = AppConnection(settings.APP_ID,
settings.SECRET_APP_KEY,
access_info["zone"],
access_token=access_info["access_token"])
def get_user_info(self):
return self.conn.describe_users()
describe_users 是 sdk 提供的一个函数,不需要额外参数,作用是返回当前的用户信息。您可以通过使用这个函数获得用户的手机号,邮箱等。创建 AppConnection 实例时,已经传入了 access_token , 当sdk发请求给青云时,会自动在请求中添加 access_token 。
青云应用除了可以访问 IAAS API , 还可以访问 APP API . APP 访问 IAAS API 时,需要做以下修改:
示例请求(请忽略换行):
https://api.qingcloud.com/app/
?access_token=gDV9PoTSwBII9Djv0GmZmSHVAxmsg6Or
&action=DescribeUsers
&app_id=app-wdpukp10
&users=usr-xxxxxx
&signature_method=HmacSHA256
&signature_version=1
&time_stamp=2015-04-20T08%3A45%3A22Z&version=1
&zone=pek2
&signature=Nnn95zJjussulpn3kfjSBE7bFFvAMKMtqk6pByIaWi8
注解
如果您使用python以外的开发语言,可以在github.com搜索qingcloud关键字,能找到绝大多数语言的sdk。这些sdk由青云用户开发,使用起来大同小异,只是需要为app调整一下参数。
由于您的青云应用是加载在iframe里面,为了自动调整iframe高度,需要在您的网页body结尾加入一段javascript代码,示例应用的模版是这样定义的:
<!DOCTYPE html>
<html>
<body>
<p>Hello {{username}}!</p>
<p>Welcome to QingCloud App</p>
<p>Your notify email address is {{notify_email}}</p>
<!-- 可以直接引用qclib库以自动设置页面高度 -->
<script type="text/javascript" src="https://console.qingcloud.com/static/dist/js/qclib.min.js">
<!-- 也可以取消自动设置,在需要的时候手动设置 -->
<script type="text/javascript" src="https://console.qingcloud.com/static/dist/js/qclib.min.js">
<script type="text/javascript" >
// 取消自动设置
QCLIB.App.setAutoSetAppHeight(false);
// 当页面是动态生成时,可以在需要时手动设置高度
var height = getPageHeight();
QCLIB.App.setAppHeight(height);
</script>
</body>
</html>
到这里,示例程序就结束了,您需要结合自己的服务特点,结合青云api为用户提供优质服务。下面介绍如何提交青云应用。
首先,您需要在青云主页注册账号,并通过工单申请成为青云合作伙伴。被认证成为合作伙伴后,就能在左侧导航栏看到“开发者”视图。进入“开发者”视图,点击“创建应用”开始创建一个新的青云应用:
其中标签代表应用的提供的功能,会影响到应用中心的分类。接下来需要输入应用的文字和图片描述。图片URL至少需要一个,以换行分隔。
接下来在应用设置里面,需要输入:
您需要根据自己服务的实际情况,向用户要求授权。用户安装应用时,有可能根据应用要求的权限,决定是否继续安装应用。
下一步个性化设置需要您输入一些信息,包括联系方式,公司网址,应用图标等。点击提交完成创建应用。
图片规格如下:
创建后,在“密钥”这一列,点击“重新生成”,拿到应用对应的密钥。您在web应用里面,需要使用这个密钥验证来自青云的请求,并签名发往青云API的请求。
注解
为了保护密钥的安全,密钥只在生成时显示一次。请妥善保管,如果丢失或泄露,重新生成一个,可以让旧密钥失效。
然后就可以在开发视图里面预览您的应用。这个时候可以结合实际情况调试一下青云应用,并调整显示效果。我们提供两种预览方式:
注解
在预览模式中,点击安装并不会安装应用。
![]()
在预览试图里面测试通过以后,就可以提交应用。青云的管理员会审核您提交的应用,通过以后能显示到应用中心里面。
用户第一次点击应用,会进入应用详情。通过点击安装按钮启用应用。下次点击应用时,就直接加载应用的URL了。