转载

客户端API请求规范

这是一份老夫制定的客户端API请求规范,现在分享出来,希望对各位有帮助。

API请求规范,兼在明确iOS/Android等native客户端请求服务端接口的协议、参数和响应结果,所有的APP必须按照这个规范与服务端进行交互。

1、请求协议

所有与服务端交互的API,都走 HTTP(S) 协议。

2、请求参数

API的请求参数分两部分,一部分为 协议参数 ,属于协议本身,与业务关务,如t,imei,appkey等;一部分为 业务参数 ,这些参数会对系统中的系统流程、操作方式产生重要的影响。

协议参数

服务端约定,客户端需在每次请求的URL里面,加上下列协议参数:

参数名 是否必须 说明
imei 必须 INTERNATIONAL_MOBILE_EQUIPMENT_IDENTITY,客户端设备标识,国际移动设备身份码
imsi 必须 INTERNATIONAL_MOBILE_SUBSCRIBER_IDENTITIFICATION_NUMBER,客户端用户标识
t 必须 TIMESTAMP,请求的时间戳,UTC 1970-1-1 0时到现在的时间差,精确到秒
appkey 必须 由服务端颁发的appkey
sign 必须 md5签名串
lng 可选 LONGITUDE,手机上获取的经度
lat 可选 LATITUDE,手机上获取的纬度
ci 可选 CHANNEL_IDENTITY ,渠道标识,格式为:channelId@应用名 平台 客户端版本,例如:1001@nzaom_android_1.0,其中1001表示应用宝

业务参数

业务具体参数由服务端在接口文档中进行约定。

2.1、参数传递

协议参数必须通过url parameter传递,业务参数通过body,path,url parameter等多样化的形式传递。

服务端提供标准的Restful API,支持 POST/DELETE/PUT/PATCH/GET 方式。

下面两个示例分别演示GET和POST的请求:

GET

GET http://localhost:80/api/testGet?appkey=123456&data=%7B%22name%22%3A%22%E5%A4%A7%E7%99%BD%22%2C%22sex%22%3A%22%E7%94%B7%22%7D&ci=1001_nzaom_android_1.0&imei=imei11111&imsi=imsi22222&lat=23.1&lng=111.21&t=1432747514991&sign=760b2c16ddd8b47288b0e16871fbd5de HTTP/1.1 Host: localhost:80 Connection: Keep-Alive User-Agent: Apache-HttpClient/4.4.1 (Java/1.7.0_51) Accept-Encoding: gzip,deflate  HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Expires: Thu, 01 Jan 1970 00:00:00 GMT Set-Cookie: SESSION=7a449d11-9a09-45b4-9c49-f43f0131ee51;Path=/ Content-Length: 49 Server: Jetty(6.1.22)  {"data": {"name":"大白","sex":"男"},message:"OK","status": 200} 

POST

POST http://localhost:80/api/testPost?appkey=123456&data=%7B%22name%22%3A%22%E5%A4%A7%E7%99%BD%22%2C%22sex%22%3A%22%E7%94%B7%22%7D&hci=1001_hehuyou_android_1.0&imei=imei11111&imsi=imsi22222&lat=23.1&lng=111.21&t=1432747714602&sign=2dfb020566c7d826e3ed7276c7c49fb8 HTTP/1.1 Content-Type: application/json;charset=UTF-8 Content-Length: 29 Host: localhost:80 Connection: Keep-Alive User-Agent: Apache-HttpClient/4.4.1 (Java/1.7.0_51) Accept-Encoding: gzip,deflate  {"name":"大白","sex":"男"}  HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Expires: Thu, 01 Jan 1970 00:00:00 GMT Set-Cookie: SESSION=13e853c2-2f55-43c6-b4f0-cb016590141a;Path=/ Content-Length: 49 Server: Jetty(6.1.22)  {"message": "权限不够","status": 403} 

2.2 参数Sign

为了减轻非法恶意请求,每次来自APP的请求都需要对请求参数进行签名以实现安全认证。通过参数sign来验证参数传递是否合法,具体流程如下:

  1. 根据参数名称(除签名sign)将所有请求参数按照字母先后顺序排序:key + value …. key + value,例如:将foo=1,bar=2,baz=3 排序为bar=2,baz=3,foo=1,参数名和参数值链接后,得到拼装字符串bar2baz3foo1

  2. 将secret拼接到参数字符串尾进行md5加密后,再转化成大写,格式是:byte2hex(md5(secretkey1value1key2value2…secret))

  3. 第2步生成的字符串即为参数sign

参考代码(Java版本):

TreeMap<String, String> tree=new TreeMap<String, String>(); Enumeration<String> enums = request.getParameterNames(); String param="";  while(enums.hasMoreElements()){   String ele = enums.nextElement();   tree.put(ele, request.getParameter(ele)); } Iterator<String> it = tree.keySet().iterator();  while( it.hasNext() ){   String v=it.next();   //System.out.println(" "+v+" decode:"+java.net.URLDecoder.decode(request.getParameter(v),"utf-8"));   if(!"sign".equals(v)){   param+=v+java.net.URLDecoder.decode(request.getParameter(v),"utf-8");   } }  param = param+SECRET; String sign2=Md5.sign(param).toUpperCase(); System.out.println("sign:"+sign); System.out.println("sign2:"+sign2); if(!sign2.equalsIgnoreCase(sign)){   System.out.println("非法访问"); } 

注意事项:

  • 所有的参数皆为utf-8格式

2.3 关于登录

服务端和客户端都是采用基于Header的用户会话状态解决方案。登录后需要将服务端返回的token设置在Header的参数X-Auth-Token中。

2.3 关于Header

目前必须传递的两个Header参数分别是:

X-Auth-Token X-Platform 

其中X-Auth-Token为会话token,X-Platform为请求的终端系统,如iOS、Android。如果涉及到API版本,请将版本的参数设置在Header中,Header的key为: X-Api-Version

3、响应结果

服务端都以json格式返回,分成功、失败两种状态。

成功:

{"data": {"name":"大白","sex":"男"},message:"OK","status": 200}  {"data": ["a","b","c"],message:"OK","status": 200} 

失败:

{"message": "权限不够","status": 403} 

4、关于错误码

400:非法请求 401:未登陆 403:权限不够 500:系统错误  900:业务级别的错误 200:正常请求 
原文  http://blog.12xiaoshi.com/2016/03/31/tech/api-constraint_design/
正文到此结束
Loading...