这是一份老夫制定的客户端API请求规范,现在分享出来,希望对各位有帮助。
API请求规范,兼在明确iOS/Android等native客户端请求服务端接口的协议、参数和响应结果,所有的APP必须按照这个规范与服务端进行交互。
所有与服务端交互的API,都走 HTTP(S) 协议。
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表示应用宝 |
业务具体参数由服务端在接口文档中进行约定。
协议参数必须通过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}
为了减轻非法恶意请求,每次来自APP的请求都需要对请求参数进行签名以实现安全认证。通过参数sign来验证参数传递是否合法,具体流程如下:
根据参数名称(除签名sign)将所有请求参数按照字母先后顺序排序:key + value …. key + value,例如:将foo=1,bar=2,baz=3 排序为bar=2,baz=3,foo=1,参数名和参数值链接后,得到拼装字符串bar2baz3foo1
将secret拼接到参数字符串尾进行md5加密后,再转化成大写,格式是:byte2hex(md5(secretkey1value1key2value2…secret))
第2步生成的字符串即为参数sign
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("非法访问"); }
服务端和客户端都是采用基于Header的用户会话状态解决方案。登录后需要将服务端返回的token设置在Header的参数X-Auth-Token中。
目前必须传递的两个Header参数分别是:
X-Auth-Token X-Platform
其中X-Auth-Token为会话token,X-Platform为请求的终端系统,如iOS、Android。如果涉及到API版本,请将版本的参数设置在Header中,Header的key为: X-Api-Version
服务端都以json格式返回,分成功、失败两种状态。
成功:
{"data": {"name":"大白","sex":"男"},message:"OK","status": 200} {"data": ["a","b","c"],message:"OK","status": 200}
失败:
{"message": "权限不够","status": 403}
400:非法请求 401:未登陆 403:权限不够 500:系统错误 900:业务级别的错误 200:正常请求