=====================
聚合鉴权 RealMe 介绍
=====================
.. role:: raw-latex(raw)
:format: latex
..
.. _header-n2:
介绍
=============
聚合鉴权平台专注企业级鉴权服务,聚合各类识别认证功能,为企业提供标准统一的鉴权服务接口和基于场景的行业解决方案。
.. _header-n3:
服务调用说明
=============
聚合鉴权 RealMe 遵循标准 HTTP 协议及 RESTful 规范,使用 HTTP
标准状态码返回接口服务调用结果,并自定义了业务级别的错误代码以提供更详细的错误描述。结果数据将以
json 格式返回,易于解析,便于扩展。
.. _header-n6:
调用前准备
~~~~~~~~~~
1) 注册并登录“\ `聚合鉴权 RealMe 网站 `__\ ”,在“应用列表”中,查看应用的 ``app_token`` 及 ``app_key``。
2) ``app_token``:调用接口服务时使用,作为调用方系统标识,建议为不同产品及不同应用 (如 web/ Android / iOS 等) 申请不同的 ``app_token``,聚合鉴权 RealMe 可帮您区分并记录不同 ``app_token`` 的使用情况。
3) ``app_key``:对请求数据加签时使用,与 ``app_token`` 一一对应,参考“签名_”。
.. _header-n14:
编码转换
~~~~~~~~
对于含中文或特殊字符等参数的请求,请在请求前做转码 (URL Encode)
,编码格式为 ``UTF-8``。
.. _header-n17:
.. _签名:
签名
~~~~
调用接口服务时,需提供请求签名 (sign)
,以保证请求数据未被篡改。签名公式为:HMAC-SHA256-HEX
(请求方式 + 服务地址 + 拼接的请求参数值,``app_key``)。
1) 请求方式:POST/GET/PUT/DELETE,当前接口的请求方式。
2) 服务地址:完整的请求 URL 地址,GET 请求不含 “ ? ” 后的参数部分。
3) 拼接的请求参数值:请求参数按照 key 的 ASCII 字符串顺序升序排列,将value 拼接后做编码转换。
4) app_key:应用列表中展示的调用方密钥值。
5) 特殊说明:对于请求值为二进制的参数 (如图片等文件),由于数据量过大,请求值取二进制数据的 MD5 值。
.. _header-n30:
调用示例
~~~~~~~~
如测试应用:
+--------------+---------+
| app_token | app_key |
+==============+=========+
| TESTRA000401 | 123456 |
+--------------+---------+
1) 确定公共请求参数及应用请求参数。
如调用身份证实名认证接口:
请求地址:\ https://realme.cloudpnr.com/realme-proxy/v4/trade/namecheck
请求参数:
order_date = 20170306
order_id = 20170119000002
app_token = TESTRA000401
full_name = 测试
id_number = 330326198511230201
video_pic = YmV0YSAgICCGL2V7kJn9XV5leMhFnH/8ShgmCGVXbZKKuQSORISK0ByujPxN9gfuTlptg7H
nHaREhJ3kC66WIkoIFN5yTl18jsoEflCEitAcr4z8TggU3lBuXGyeuAR+RIWK0ByuniJOKRTeYE5cbIq5BH
5EhJ72INyM/FYIFN5MT
source_channel = 0
imei =
mer_bg_url = http://test.chinapnr.com/recv
2) 生成签名值。
- 请求方式为 ``POST``,
服务地址为 https://realme.cloudpnr.com/realme-proxy/v4/trade/namecheck
- 请求参数含图片,
对图片做 32 位 ``MD5``,并全转为大写,得到:EBECFDBCF6D86D558781C110C9623661
- 请求参数按照 key 的 ASCII 字符串顺序升序排列,将 value 拼接,得到:
330326198511230201http://test.chinapnr.com/recv40170306201701190000020EBECFDBCF6D86
D558781C110C9623661
- 请求方式、服务地址与请求参数值拼接,得到:
POSThttps://realme.cloudpnr.com/realme-proxy/v4/trade/namecheck330326198511230201ht
tp://test.chinapnr.com/recv40170306201701190000020EBECFDBCF6D86D558781C110C9623661
- 使用 ``app_key`` 作为密钥,对获得的字符串 (message) 做HMAC-SHA256,得到签名:
cb3c818a286ca47f1f92c6cf235923c8285b8bbfb190d274e806125dd50c2a5f
.. code:: java
public static String HMACSHA256(byte[] data, byte[] key) {
try {
SecretKeySpec signingKey = new SecretKeySpec(key, "HmacSHA256");
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(signingKey);
return byte2hex(mac.doFinal(data));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
return null;
}
public static String byte2hex(byte[] b) {
StringBuilder hs = new StringBuilder();
String stmp;
for (int n = 0; b != null && n < b.length; n++) {
stmp = Integer.toHexString(b[n] & 0XFF);
if (stmp.length() == 1)
hs.append('0');
hs.append(stmp);
}
return hs.toString();
}
3) 发送请求。
.. code:: java
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("https://realme.cloudpnr.com/realme-api/v4/trade/staticfacecheck");
try {
List nvps = new ArrayList();
nvps.add(new BasicNameValuePair("order_date","20170101"));
nvps.add(newBasicNameValuePair("order_id", "201701010000001"));
nvps.add(newBasicNameValuePair("app_token", "TESTRA000401"));
nvps.add(new BasicNameValuePair("sign","cb3c818a286ca47f1f92c6cf235923c8285b8bbfb190d274e806125dd50c2a5f"));
.......//TODO 添加所有参数
post.setEntity(new UrlEncodedFormEntity(nvps));
post.addHeader(“env”, ”test”);
HttpResponse httpResponse = client.execute(post);
int code = httpResponse.getStatusLine().getStatusCode();
String returnStr = EntityUtils.toString(httpResponse.getEntity());
} catch (Exception e) {
e.printStackTrace();
}
.. _header-n80:
异步结果通知
~~~~~~~~~~~~
1) 对于无法实时返回处理结果的请求,聚合鉴权 RealMe 仅返回请求已接收,并将在请求处理完成后,把处理结果以 ``post`` 方式发送至调用方指定的接收地址。
2) 每个异步结果通知将有一个唯一标识,一般为系统流水号 ``seq_id``。在接收到异步结果后,请输出 ``“RECV_ORD_ID_唯一标识”``,告知聚合鉴权 RealMe 已接收到异步结果。
3) 出于数据安全考虑,建议接收地址使用更安全的 HTTPS 协议地址。
异步结果通知处理示例:
.. code:: java
String seqId = "";
String returnCode = "";
String returnMessage = "";
for (em = request.getParameterNames(); em.hasMoreElements();) {
String key = em.nextElement().toString();
String value = request.getParameter(key);
if(StringUtils.equals(key, "seq_id")) {
seqId = value;
} else if (StringUtils.equals(key, "return_code")){
returnCode = value;
} else if (StringUtils.equals(key, "return_message")){
returnMessage = value;
}
}
if(StringUtils.isNotBlank(seqId)) {
getWriter().print("RECV_ORD_ID_"+seqId);
}