1 开放平台API (作者:姜鹏)

1.1 API对接

1.1.1 开发者API对接流程

开发者对接开放平台API流程,请参考下图:

1.1.2 API 签名

由于SHA-1和RSA-1024已过时且安全性较低,因此SHA-256和RSA 2048是当前的标准。SHA-256是一种非常好的安全散列算法,非常适合在证书上使用,而2048位RSA是一种很好的签名算法(注意签名与加密不同)。使用带有SHA-256的2048位RSA是证书的安全签名方案。本签名方案采用SHA-256和RSA2048.

step1 生成签名串:

appId\n
appSecret\n
method\n
url\n
noncestr\n
timestamp\n
body\n

说明:按照以上格式将7个参数按顺序排成7行。

签名参数 类型 是否必要 说明
appId String Y 开放平台应用Id
appSecret String Y 开放平台应用密钥
method String Y Http的请求类型 , POST,GET,DELETE 等,一律大写
url String Y Http的请求URL,含参数,以/开头,不含服务器域名和端口, 有参数请按参数的ASCII码升序拼接。如:请求URL为:https://api-sit.remacsmart.com/open/account/get?account_type=remac&id=1029&year=2021,实际url取值为:/open/account/get?account_type=remac&id=1029&year=2021,参数要按ASCII保证顺序
noncestr String Y 32位随机字符串,在5分钟内有重复的随机字符串将视为重复请求。生成方法参照:UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
timestamp String Y 系统时间戳,秒为单位,长度10位,如:1649715582, 当开发者应用传参时间戳与平台接收到请求的时间戳相差10秒将被视为过期请求。生成方法参考:String.format("%d",System.currentTimeMillis()/1000)
body String Y http 请求体,非表单参数。无值用\n表示独占一行。JSON参数顺序按ASCII码升序排序,如有嵌套JSON,嵌套JSON中的参数也遵循按ASCII码升序排序。

Step2 开发者利用平台私钥对签名串进行签名

引入睿智云开放平台签名SDK

<dependency>
   <groupId>com.remac.opencloud</groupId>
  <artifactId>remac-open-signature</artifactId>
  <version>1.0</version>
</dependency>

调用签名SDK完成签名。


String privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" +
                  "MIICXAIBAAKBgQC7NmfnT4MaT/NtadggelMRpNIY6Fb7vyAGBSZFbhgNSQaSJqGH\n" +
                  "UWsyHpyr+DOt15erardcncrxvIrWuzxWJa123jnDwHjrTFEZCTbuwoIwaEnNqStR\n" +
                  "uWY2RqTLqzFcUH73lLaOiIyuEKylPL8+ypHv7JBzzn9q5vIdu3P4kKlItwIDAQAB\n" +
                  "AoGANmx+kDQBPOj5L1mRxv9Intx3Z15DyzOor5dXpN94hoQwMNSiKKB2tT9I9IVX\n" +
                  "ILaIFQEVBQuqL9RL2FjeFX0mi+QIRoVmquEwRC0lb5dp2KyYQF7/NHoZkQacZMYe\n" +
                  "0+XHjn8vf9sKz0/E0WQmt4CBvrDzbUgP3WyvpZaNbTf88KECQQDvorD4MU1wQ7nk\n" +
                  "furTFiDp8jcTwIrpmPllO5y1wZXy4xHxaYkvyfPngoHrvCHh+qZ29t2wMeaNxnjG\n" +
                  "Mt+WNu79AkEAx/9Bd21lv70bq9GW3q/xTuyeEI8CdD31Vwud97MKL+CHb2hWavH+\n" +
                  "VPeZfpa1ZqqKFOEl9DP3hai9AeXx1L2WwwJAHCp8MH/jAToEpHXCdhMYxUah8KFl\n" +
                  "8nT3g02Ras+ZJ1ZHKp/j7wkGsQRm7uVK+juyyzLS9b23wpw8X9dk7kwApQJBAJI+\n" +
                  "um2NRpENxNVAfrU6LReMeQ0ctiuwPt429X1yo6lc40x5HHA5osQZBloF9IIthKk9\n" +
                  "9lX7Ri2rtQJVViA9vqcCQBRx4QsL/dZ6zZpW+BPNl8wFhvgfguXDfNzL7A3QA45k\n" +
                  "4OPqj5hw1e8PYB45ZG0K5WkknpLAtzDpxiMQWoj+u9w=\n" +
                  "-----END RSA PRIVATE KEY-----\n";

          SignUtil util = new SignUtil(privateKey);
          String appId = "remac16800901";
          String appSecret = "9lX7Ri2rtQJVViA9vqcCQBRx4QsL/dZ6zZpW+BPNl8wFhvgfguXDfNzL7A3QA45k";
          String url = "/account/get?id=1108";
          String method = "GET";
          String noncestr =  UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
          String timestamp = String.format("%d",System.currentTimeMillis()/1000);
          String body = null;
          String message = util.buildMessage(appId,appSecret,method, url,noncestr, timestamp, body);
          System.out.println("--->签名串:"+message);
          long start = System.currentTimeMillis();
          String signature = util.sign(privateKey,message );
          System.out.println("--->签名:signature="+signature);
          long end  = System.currentTimeMillis();
          System.out.println("--签名耗时:"+(end-start)+" 豪秒");

执行结果:

--->签名串:remac16800901
9lX7Ri2rtQJVViA9vqcCQBRx4QsL/dZ6zZpW+BPNl8wFhvgfguXDfNzL7A3QA45k
GET
/account/get?id=1108
64c3a85b5b8d4216966652a42078c3c9
1649657739
null
--->签名:
signature=E1ucuUvX6VqxtFewl9LS2nl66fyZ2LaJ/DE/vaqM2rvaKOu0wFoGHJ1l3fELqvYJT6LMYpF7vxbzo3u8EZIg2Z0xCfY9mBYnuN+XXnmxbjJt2cDMkvJ+tXS8qOXACQNMghco+Ek90OrfrYA6CkOUA4VRV0/Y2N/wISN50US5XS8=
--签名耗时:946 豪秒

step3 构造一个包含签名的Http头部信息

将生成的签名与其他信息一起按照格式放入请求头signToken中,请求头格式为:

signToken: 认证类型 固定参数(含签名)

其中, 认证类型固定为:REMAC-SHA256-RSA2048

固定参数(含签名): 将必要的appId, appSecret, nocestr, timestamp,signature 以健值对key=value加逗号隔开,无顺序要求。

示例:

signToken: REMAC-SHA256-RSA2048 appId=remac16800901,appSecret=9lX7Ri2rtQJVViA9vqcCQBRx4QsL/dZ6zZpW+BPNl8wFhvgfguXDfNzL7A3QA45k,noncestr=462e70c75cee42fcad7b8bd54b1ee4e0,timestamp=1649717011,signature=PxJgOwB1q4SnNbBAlb3hhuL+DnPcEmpVoZzgGIgUWISQVJxg66y+VIBRSwr0wyv7Qyw+osWJERr5IeEaHdjmOOq6KV0Iu9zDBTdH23dAoYyvK6uxcQolI3Wx5/pz+KcwsgzZ5JqKgQFcjnZWGOfJPDKwS4cKQcuEf9LuVCG4py8=

step4 调用睿智云开放平台接口,将签名值携带在http 请求头部。

参考源码:

 // 开放平台API测试环境域名
          // String domain = "https://api-sit.remacsmart.com";
          //// 开放平台API生产环境域名
          String domain = "https://api.remacsmart.com";

          String privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" +
                  "MIICXAIBAAKBgQC7NmfnT4MaT/NtadggelMRpNIY6Fb7vyAGBSZFbhgNSQaSJqGH\n" +
                  "UWsyHpyr+DOt15erardcncrxvIrWuzxWJa123jnDwHjrTFEZCTbuwoIwaEnNqStR\n" +
                  "uWY2RqTLqzFcUH73lLaOiIyuEKylPL8+ypHv7JBzzn9q5vIdu3P4kKlItwIDAQAB\n" +
                  "AoGANmx+kDQBPOj5L1mRxv9Intx3Z15DyzOor5dXpN94hoQwMNSiKKB2tT9I9IVX\n" +
                  "ILaIFQEVBQuqL9RL2FjeFX0mi+QIRoVmquEwRC0lb5dp2KyYQF7/NHoZkQacZMYe\n" +
                  "0+XHjn8vf9sKz0/E0WQmt4CBvrDzbUgP3WyvpZaNbTf88KECQQDvorD4MU1wQ7nk\n" +
                  "furTFiDp8jcTwIrpmPllO5y1wZXy4xHxaYkvyfPngoHrvCHh+qZ29t2wMeaNxnjG\n" +
                  "Mt+WNu79AkEAx/9Bd21lv70bq9GW3q/xTuyeEI8CdD31Vwud97MKL+CHb2hWavH+\n" +
                  "VPeZfpa1ZqqKFOEl9DP3hai9AeXx1L2WwwJAHCp8MH/jAToEpHXCdhMYxUah8KFl\n" +
                  "8nT3g02Ras+ZJ1ZHKp/j7wkGsQRm7uVK+juyyzLS9b23wpw8X9dk7kwApQJBAJI+\n" +
                  "um2NRpENxNVAfrU6LReMeQ0ctiuwPt429X1yo6lc40x5HHA5osQZBloF9IIthKk9\n" +
                  "9lX7Ri2rtQJVViA9vqcCQBRx4QsL/dZ6zZpW+BPNl8wFhvgfguXDfNzL7A3QA45k\n" +
                  "4OPqj5hw1e8PYB45ZG0K5WkknpLAtzDpxiMQWoj+u9w=\n" +
                  "-----END RSA PRIVATE KEY-----\n";

          SignUtil util = new SignUtil(privateKey);
          String appId = "remac16800901";
          String appSecret = "9lX7Ri2rtQJVViA9vqcCQBRx4QsL/dZ6zZpW+BPNl8wFhvgfguXDfNzL7A3QA45k";
          String url = "/account/query?id=1108";
          String method = "POST";
          String noncestr =  UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
          System.out.println("--->noncestr="+noncestr);
          String timestamp = String.format("%d",System.currentTimeMillis()/1000);
          System.out.println("--->timestamp ="+timestamp );
          JSONObject  reqBody  = new JSONObject();
          reqBody .put("name", "张三");
          reqBody .put("account_type", "remac");
          String body = reqBody.toJSONString();
          //step1 构造签名串
          String message = util.buildMessage(appId,appSecret,method, url,noncestr, timestamp, body);
          System.out.println("--->签名串:"+message);
          long start = System.currentTimeMillis();
          //step2 生成签名
          String signature = util.sign(privateKey,message );
          System.out.println("--->签名:signature="+signature);
          long end  = System.currentTimeMillis();
          System.out.println("--签名耗时:"+(end-start)+" 豪秒");
          //step3 http调用睿智云中台接口
          int connectTimeOut = 10;
          int readTimeOut = 5;
          int writeTimeOut = 5;
          int maxIdleConnections = 100;
          long keepAliveDuration = 300L;
          OkHttpUtil  httpUtil = new  OkHttpUtil(connectTimeOut, readTimeOut, writeTimeOut, maxIdleConnections, keepAliveDuration);
          // 头部携带签名
          Map<String, String> headers = new HashMap<>();

          String header = util.buildHeader( appId,appSecret,noncestr,timestamp, signature);
          System.out.println("--->header value="+header);

          headers.put("signToken", header);
          String api = domain+url;

          Response response = httpUtil.post(null, api,  body, headers);

          String res = response.body().string();

          System.out.println("--->收到开放平台的返回结果JSON:"+res);

参见源码:http://10.18.69.218/remac-mid/remac-open-signature/blob/master/src/main/java/com/remac/open/signature/sdk/SignUtil.java

1.1.2.1 开放平台调试API

(1) 调用GET 请求

https://api-sit.remacsmart.com/v1/open/fake/account?id=XX

其中id 为任意字符串

正确响应:

{

   "code": "200",
   "message":"success",
   "data": {

         "id":"XXX",
         "user_name":"fake01",
         "avatar":"https://iot-main-oss.oss-cn-hangzhou.aliyuncs.com/icons/monkey.png"
   }


}

(2) 调用 POST 请求

https://api-sit.remacsmart.com/v1/open//fake/submit

reqBody: HTTP请求体, 用户自定义一个JSON ,在返回结果的data 原样输出

正确响应:

{

   "code": "200",
   "message":"success",
   "data": {

          开发者传HTTP请求体原样输出
   }


}

1.1.4 API 安全规范

任何调用开放平台的请求,须按《1.1.2 API 签名》规定生成签名,在http头部携带签名标识,约定如下:

http 头部名称: signToken , 值: 开发者按《1.1.2 API 签名》规定生成的签名。

1.1.5 开放平台接口响应约定

1.1.5.1 响应格式

正确响应:

 {
    "code": "200",
    "message":"success",
    "data": {

          "result":[{...},{..}]
    }

 }

错误响应:

 {
    "code": "非200",
    "message":"错误提示"


 }

1.1.5.2 错误码

code message 说明
10001 开发者应用密钥错误
10002 开发者应用ID不存在
10003 签名格式不正确
10004 缺少头部signToken
10005 签名中必要参数缺失
10006 开发者应用IP不在白名单中
10007 请求重复
10008 请求已过期
10009 开发者应用未关联开发者帐号
10010 平台未找到开发者公钥
10011 随机字符串noncestr非法
10012 请求时间戳非法
10013 验签失败
9999 通用错误码

1.2 文档

1.2.1 文档范围

所有需要访问睿智云开放平台标准API的开发者。

1.2.2 文档列表

1.2.3 全局字典

字典key 类型 字典Value 字典value意义
account_type Int 1 个人开发者
2 企业开发者

1.3 开放平台API

使用对象: 开发者。

1.3.1 开发者帐号

1.3.1.1 开发者帐号注册

URL: /v1/open/account/register

method : POST

body 约定:

字段 类型 说明 是否必填
account_type int 开发者帐号类型,见《1.2.3 全局字典》 y
user_name String 用户名,可以为手机号 6-12 字符长度。 y
nick_name String 用户昵称, 1-32 字符长度 n
avatar String 用户头像,<=200个字符长度 n
pwd String 用户密码, 明文6-12 字符长度。规范见《http://arch.smartmideazy.com/docs/account/account-doc.html【5.2 密码明文加密】》 y
enabled Int 1: 激活 2:禁用 3: 临时锁定 ; 默认1. n
materials JSONObject 开发者资料 n

开发者资料 materials

个人开发者materials对象各字段约定如下:

字段 类型 说明 是否必填
id_no int 身份证编码 y
id_photo_face byte[] 身份证人像面 y
id_photo_nation byte[] 身份证国徽面 y
valid_time_span Array 身份证有效期 ["2009-09-01", "长期"] y

企业开发者materials对象各字段约定如下:

字段 类型 说明 是否必填
id_no int 法人(代运营者)身份证编码 y
id_photo_face byte[] 法人(代运营者)身份证人像面 y
id_photo_nation byte[] 法人(代运营者)身份证国徽面 y
valid_time_span Array 法人(代运营者)身份证有效期 ["2009-09-01", "长期"] n
legal_type Int 1: 法人 2: 代运营者 y
certificate_proof byte[] 代运营者加盖企业公章的证明函。模板从开放平台下载。 N; 代运营者须上传加盖企业公章的证明函。
business_certificate byte[] 公司营业执照 Y
business_no String 统一社会信用号 Y
tel String 联系电话 Y

返回字段:

字段 类型
id Biting 帐号主键
account_type int 开发者帐号类型,见《1.2.3 全局字典》
user_name String 用户名,可以为手机号 6-12 字符长度。
nick_name String 用户昵称, 1-32 字符长度
avatar String 用户头像,<=200个字符长度
lock_time String yyyy-MM-dd HH:mm:ss 格式。帐号锁定时间。同一天最大密码重试次数达5次将被锁定,登录功能限制。次日方可重试。
enabled Int 1: 激活 2:禁用 3: 临时锁定
last_login_time String yyyy-MM-dd HH:mm:ss 格式。帐号最近一次成功登录时间
register_time String yyyy-MM-dd HH:mm:ss 格式。注册时间

1.3.1.2 开发者帐号安全-绑定手机号

URL: /open/account/bind/mobile

method : POST

body 约定:

字段 类型 说明 是否必填
id bigint 开发者帐号主键ID y
mobile String 手机号码 y
verify_code String 6位短信随机码 y

1.3.1.3 开发者帐号安全-绑定邮箱

URL: /open/account/bind/mobile

method : POST

body 约定:

字段 类型 说明 是否必填
id Biting 开发者帐号主键ID y
email String 电子邮件地址 y
verify_code String 平台向开发者邮箱发送6位确认码。 y

1.3.1.4 开发者帐号找回-手机号找帐号

URL: /open/account/fetch/mobile

method : POST

body 约定:

字段 类型 是否必填
mobile String 开发者手机号 y
verify_code String 平台向开发者发送的6位手机验证码 y

1.3.1.5 向开发者邮箱发送确认码及链接

URL: /open/account/fetch/email

method : POST

body 约定:

body 约定:

字段 类型 说明 是否必填
email String 电子邮件地址 y

成功执行后返回结果:

字段 类型 说明 是否必返回
verify_code String 平台发送的邮箱确认码 N
expired_in int 过期时间。将在expired_in分钟后过期 N
makesure_url String 开发者邮箱中找回帐号的链接 N

1.3.1.6 开发者帐号找回-邮箱找帐号

URL: /open/account/fetch/email

method : POST

body 约定:

字段 类型 说明 是否必填
email String 电子邮件地址 Y
verify_code String 6位手机确认码 Y
nonce_str String 平台生成的随机码 Y

返回:

{

  "code":"200",
  "message":"success",
  "user_name":"betty2022"

}

返回字段说明

字段 类型 说明 是否必返回
user_name String 开发者帐号 N; 仅帐号找回成功才返回此字段

1.3.1.7 开发者重置密码

URL: /open/account/pwd/reset

method : POST

body 约定:

字段 类型 说明 是否必填
user_name String 开发者帐号 Y
pwd String 开发者新密码 Y
random_code String 平台生成6位随机验证码 Y

返回:

{

  "code":"200",
  "message":"success",


}

1.3.2 开发者应用

1.3.2.1 应用创建

描述: 开发者可以创建多个应用。

URL: /open/app/create

method : POST

body 约定:

字段 类型 说明 是否必填
app_name String 应用名称[4-32]字符长度 Y
app_logo Byte[] 应用LOGO, 长 120像素 宽 120像素 清晰。 Y
app_discription String 应用介绍。200字符以下。 Y
app_type String 行业类型编码 (待补充) Y

返回:

{

  "code":"200",
  "message":"success",
  "data": {

     "id":1120,
     "app_key":"109667788",
     "app_sectet":"VrG8kPpCGFWs25NpOQelaYtrDd1Cg0YdBIKqJIgknojatWo6DcV5P", 

  }

}

成功返回:

字段 类型 说明 是否必填
id bigint 应用主键ID Y
app_key String 开发者应用帐号 Y
app_secret String 开发者应用密钥 Y
account_id Biting 开发者帐号主键ID Y

1.3.2.2 开发者公私钥设置

描述:

URL: /open/api/key/set

method : POST

body 约定:

字段 类型 说明 是否必填
account_id Bigint 开发者帐号主键ID
private_key String 开发者私钥。2048 长度RSA公私钥,开发者个人保存。 Y
public_key String 开发者公钥。平台需要保存。 Y
status Int 1:启用2:禁用。默认为启用。 Yid
id Bigint 开发者API配置表主键ID。N; 此值为空代表新增。非空代表修改

1.3.2.3 开发者AES加密密钥设置

描述: 用于开发者应用与平台通讯协议需要加解密的场合。

URL: /open/api/aes/set

method : POST

body 约定:

字段 类型 说明 是否必填
account_id Biting 开发者帐号主键ID
aes_key String 开发者AES密钥。长度32位。 Y
id Bigint 开发者API配置表主键ID N; 此值为空代表新增。非空代表修改

1.3.2.4 开发者IP白名单

描述: 开发者将自己的应用部署环境的IP作为白名单配置在平台,进一步提升开发者应用与开放平台之间的安全性。

URL: /open/api/ip/set

method : POST

body 约定:

字段 类型 说明 是否必填
account_id Biting 开发者帐号主键ID
aes_key String 开发者AES密钥。长度32位。 Y
id Bigint 开发者API配置表主键ID N; 此值为空代表新增。非空代表修改

1.4 开放平台后台API

对象: 开放平台管理员。

1.4.1 开发者帐号审核

URL: /open/admin/account/audit

method : POST

body 约定:

字段 类型 说明 是否必填
user_name String 开发者帐号 Y
status Int 1: 通过 2:拒绝 Y

返回:

{

  "code":"200",
  "message":"success",


}

1.4.2 开发者帐号列表

URL: /open/admin/accounts

method : POST

body 约定:

字段 类型 说明 是否必填
pageNo String 开发者帐号 Y
pageSize Int 1: 通过 2:拒绝 Y
key_word String 根据帐号、手机号、邮箱模糊搜索 N

返回:

{

  "code":"200",
  "message":"success",
  "data": {

      "pageNo":2,
      "pageSize": 20, 
      "total": 112000,
      "result": [

           {...},... {...}

      ]



  }


}

2 开放平台与现有的平台架构关系

3 测试数据

3.1 平台管理员新增开发者平台登录帐号

POST https://gw-sit.remacsmart.com/v1/open/account/register

请求:

{
   "acount_type": 1,

   "user_name": "remac",
   "pwd":"a123456", 
   "nick_name":"Love flower"


}

返回:

{
  "code": "200",
  "data": {
    "id": 1,
    "user_name": "remac",
    "nick_name": "Love flower",
    "avatar": null,
    "pwd": "$2a$10$T24vHSxpDDuaYrWq.XE80eWyCfo109Koi9b37qQBpxmvPXqf0tcvO",
    "materials": null,
    "update_time": "2022-04-24 18:12:39",
    "enabled": null
  },
  "message": "success"
}

3.1 平台管理员新增开发者应用

POST https://gw-sit.remacsmart.com/v1/open/app/register

{
    "account_id": 1,
    "app_name", "睿智云智慧社区", 
    "aes_key": "goodblessme20220",
    "aes_encrypt" : 1     


}
Copyright © www.remacsmart.com/ 2021 all right reserved,powered by Gitbook该文件修订时间: 2022-12-03 13:49:25

results matching ""

    No results matching ""