OpenSearch服务会对每个访问的请求进行身份验证,通过使用Access Key ID和Access Key Secret进行对称加密的方法来验证请求的发送者身份。Access Key ID和Access Key Secret由阿里云官方颁发给访问者(可以通过阿里云官方网站申请和管理),其中Access Key ID用于标识访问者的身份;
Access Key Secret是用于加密签名字符串和服务器端验证签名字符串的密钥,必须严格保密,只有阿里云和用户知道。
支持应用类型
V3 版API 支持对高级版及标准版应用进行操作
通信协议
只支持HTTP协议
请求方法
搜索需使用GET方式,推送数据需使用POST方式
也需要包含上面提到的这些相关的请求Header
Authorization 字段计算方法
需在 HTTP 请求 Header 头信息中增加 Authorization(授权)来包含签名(Signature)信息,表明该请求已被授权,请求Header 中也需要包含文档下面“签名示例”部分中“请求Header”中提到的这些相关的请求Header。
请求 Header 中包含的参数都必须要参与签名(例如 Content-Md5,Content-Type,Date,Http专有 Header 等等)。
按照RFC2104的定义,使用上面的用于签名的字符串计算签名HMAC值
- 签名的方法用 RFC 2104 中定义的 HMAC-SHA1 方法
- 签名的字符串必须为UTF-8格式
- 含有中文字符的签名字符串必须先进行UTF-8编码,再与AccessKeySecret计算最终签名
- 签名参数先后顺序,必须和上面保持一致
查询请求
- Header 中的参数值必须要与对应签名方法中的参数值一致
- 理论上 Content-Md5,Content-Type,Date,CanonicalizedOpenSearchHeaders,Authorization 这些参数都需要添加到请求Header中,只包含必须参数可能会出现报错,需避免
- 请求 Header 中包含的参数都必须要参与签名
推送请求
- Header 中的参数值必须要与对应签名方法中的参数值一致
- 理论上 Content-Md5,Content-Type,Date,CanonicalizedOpenSearchHeaders,Authorization 这些参数都需要添加到请求Header中,只包含必须参数可能会出现报错,需避免
- 请求 Header 中包含的参数都必须要参与签名
构建CanonicalizedOpenSearchHeaders的方法
所有以 X-Opensearch- 为前缀的 Http专有 Header 被称为 CanonicalizedOpenSearchHeaders,其他非 Http专有 Header 将不被纳入验证
将所有以 X-Opensearch- 为前缀的Http专有 Header 对应的内容补齐,例如X-Opensearch-Nonce : 150224365226248(该Nonce参数值,可由10位时间戳+5位随机值(10000~99999)组合而成,例如150224365226248),再去除所有值为空的Http专有 Header
将这些有对应内容值的Http专有 Header 按照名称的字典序进行升序排序
再将这些排序后的专有 Header名,全部转换成小写字母,例如将 X-Opensearch-Nonce : 150224365226248转换成 x-opensearch-nonce : 150224365226248
删除请求头和内容之间分隔符两端出现的任何空格。例如该 x-opensearch-nonce : 150224365226248 参数,删除两端空格后为:x-opensearch-nonce:150224365226248
最后将每个请求头及对应内容作为一个单位项,再将每一项之间用 \n 连接拼成最后的 CanonicalizedOpenSearchHeaders,注意最后一个也要有 \n
[backcolor=transparent]注意:
- 若查询请求Header中不包含此处Http专有 Header,即该参数中一个Http专有 Header都没有,则无需 \n,只需在签名方法中去掉该CanonicalizedOpenSearchHeaders签名参数即可,该参数不参与签名计算。
- 将Http专有 Header添加到Header中时,不能是转换后的小写形式,需按原格式显示
构建CanonicalizedResource的方法
- 签名的字符串必须为UTF-8格式,且含有中文字符的签名字符串必须先进行 UTF-8 编码,再与 AccessKeySecret 计算最终签名
- 查询 CanonicalizedResource = path + ? + query
- 推送 CanonicalizedResource = path
构建 path 部分
对 path 进行urlencode后,再替换 %2F 为 /,下面的app_schema_demo需替换为自己应用名,常见 path 如下所示
- search查询path /v3/openapi/apps/app_schema_demo/search
- suggest查询path /v3/openapi/apps/app_schema_demo/suggest/suggest/search
- 最终查询指定应用信息查询请求串,下面“appid”需替换为待查询的应用ID,需包含Authorization授权签名参数(无需指定查询参数) /v3/openapi/apps/appid
- 推送数据path(tab 是要推送到应用中的某个具体表名,也需替换为自己应用表名)/v3/openapi/apps/app_schema_demo/tab/actions/bulk
<a name="构建 query 部分
" class="reference-link" style="box-sizing: border-box; color: rgb(0, 193, 224); transition: color 0.2s; font-weight: inherit; background: 0px 0px;">构建 query 部分
query 部分由查询参数构成,参数为键值对形式
- 为需要指定的查询参数设置对应的参数值,并去掉value为空的参数(value为空的参数不计算签名)
- 再对每一个参数按照先比较参数名后比较参数值的顺序,按照字典升序
- 再对每一部分的参数名和参数值进行 urlencode,再将参数名和对应参数值之间通过=拼接
- 再将各个查询参数之间用 & 分割拼接并存储到 query 字符串中
- 再将该 query 字符串中的 + 字符,替换成 %20
- 最后按照 path + ? + query 方式拼接至CanonicalizedResource字符串中,即完成查询操作CanonicalizedResource参数构建,示例如下/v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=config%3Dformat%3Afulljson&&query%3Dname%3A%27%E6%96%87%E6%A1%A3%27&&sort%3Did
[backcolor=transparent]注意:
- query参数中各个查询子句之间必须要用 && 进行拼接
- 若为推送操作,则只需将 path 部分拼接至 CanonicalizedResource 字符串中即可
构建 Authorization 字段
构建方法参考开头部分描述,需添加到请求 Header 中
- 假如AccessKeyId 为LTAIvDPtKBhpSPki,Signature为 1iAIX7FA8Ej4//m2DIVAPWIsVEc=,python3示例代码如下
- [backcolor=transparent]headers[backcolor=transparent][[backcolor=transparent]'Authorization'[backcolor=transparent]][backcolor=transparent] [backcolor=transparent]=[backcolor=transparent] [backcolor=transparent]'OPENSEARCH '[backcolor=transparent] [backcolor=transparent]+[backcolor=transparent] [backcolor=transparent]'LTAIvDPtKBhpSPki'[backcolor=transparent] [backcolor=transparent]+[backcolor=transparent] [backcolor=transparent]':'[backcolor=transparent] [backcolor=transparent]+[backcolor=transparent] [backcolor=transparent]'1iAIX7FA8Ej4//m2DIVAPWIsVEc='[backcolor=transparent].[backcolor=transparent]decode[backcolor=transparent]([backcolor=transparent]'utf-8'[backcolor=transparent])
签名示例
假如参数值如下
- Authorization值为OPENSEARCH LTAIvDPtKBhpSPki:DzhOHAOO+vmlBzHR2ApD/3Hpyhc=
- AccessKeySecret值为 5OCGljiVeXLvO49QaEYuYQjUb1HAZQ
- 请求方式为GET
- Content-MD5值为空,此处作为查询请求
- Content-Type值为application/json
- Date值为2017-08-09T01:54:12Z
- CanonicalizedOpenSearchHeaders值为x-opensearch-nonce:150224365226248
- CanonicalizedResource值为/v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=config%3Dformat%3Afulljson&&query%3Dname%3A%27%E6%96%87%E6%A1%A3%27&&sort%3Did
[backcolor=transparent]注意:
- 请求Header中参数值需与签名方法中对应参数值保持一致
可用以下方法计算签名(Signature)
- 以 hash_hmac 和 base64_encode 编码生成加密值作为Signature
python3 示例代码:
假如AccessKeySecret值为 5OCGljiVeXLvO49QaEYuYQjUb1HAZQ 那么通过上面的签名方法构造出来的签名值为DzhOHAOO+vmlBzHR2ApD/3Hpyhc=
构建请求串
请求串 = host + CanonicalizedResource
需在 HTTP 请求 Header 头信息中增加 Authorization(授权)来包含签名(Signature)信息,表明该请求已被授权,同时Header中也需要包含上面提到的这些相关的请求Header。(host为应用访问API地址)
v3api签名Demo(python)
目前已对外公开 v3版官方Java SDK 和 PHP SDK,且PHP SDK已包含v3api签名过程实现源码,直接调用这些方法即可使用,也可参考 PHP SDK 签名实现过程源码,或参考本文档v3api签名过程来实现其它语言SDK。
因目前官方暂未提供python版 SDK,为方便用户参考实现该文档描述签名过程,此处提供 python 查询签名Demo,以供用户参考实现本文档签名操作
【特别注意】
- 此处提供 Demo 仅供参考使用,后续用户参考此Demo实现的 SDK 由用户自己维护
- 使用 C# 语言实现本文档中v3版api鉴权,经过测试确认会有问题,在设置请求Header中的Date参数时,该Date参数值无法设置成符合我们规定的时间格式内容,.NET框架中强制指定了该请求Header中的Date参数为时间类型,不能为字符串类型(因此C#用户需考虑通过其它语言来实现v3版api查询及推送操作鉴权功能,或通过其它脚本语言实现v3版api查询及推送操作鉴权功能,再将该功能嵌入C#中,通过调用该嵌入功能来实现查询及推送操作)