App与服务器的通信接口如何设计得好,需要考虑的地方挺多的,在此根据我的一些经验做一些总结分享,旨在抛砖引玉。

安全机制的设计

现在,大部分App的接口都采用RESTful架构,RESTFul最重要的一个设计原则就是,客户端与服务器的交互在请求之间是无状态的,也就是说,当涉及到用户状态时,每次请求都要带上身份验证信息。实现上,大部分都采用token的认证方式,一般流程是:

  1. 用户用密码登录成功后,服务器返回token给客户端;

  2. 客户端将token保存在本地,发起后续的相关请求时,将token发回给服务器;

  3. 服务器检查token的有效性,有效则返回数据,若无效,分两种情况:

  • token错误,这时需要用户重新登录,获取正确的token

  • token过期,这时客户端需要再发起一次认证请求,获取新的token

然而,此种验证方式存在一个安全性问题:当登录接口被劫持时,***就获取到了用户密码和token,后续则可以对该用户做任何事情了。用户只有修改密码才能夺回控制权。

如何优化呢?第一种解决方案是采用HTTPS。HTTPS在HTTP的基础上添加了SSL安全协议,自动对数据进行了压缩加密,在一定程序可以防止监听、防止劫持、防止重发,安全性可以提高很多。不过,SSL也不是绝对安全的,也存在被劫持的可能。另外,服务器对HTTPS的配置相对有点复杂,还需要到CA申请证书,而且一般还是收费的。而且,HTTPS效率也比较低。一般,只有安全要求比较高的系统才会采用HTTPS,比如银行。而大部分对安全要求没那么高的App还是采用HTTP的方式。

我们目前的做法是给每个接口都添加签名。给客户端分配一个密钥,每次请求接口时,将密钥和所有参数组合成源串,根据签名算法生成签名值,发送请求时将签名一起发送给服务器验证。类似的实现可参考OAuth1.0的签名算法。这样,***不知道密钥,不知道签名算法,就算拦截到登录接口,后续请求也无法成功操作。不过,因为签名算法比较麻烦,而且容易出错,只适合对内的接口。如果你们的接口属于开放的API,则不太适合这种签名认证的方式了,建议还是使用OAuth2.0的认证机制。

我们也给每个端分配一个appKey,比如Android、iOS、微信三端,每个端分别分配一个appKey和一个密钥。没有传appKey的请求将报错,传错了appKey的请求也将报错。这样,安全性方面又加多了一层防御,同时也方便对不同端做一些不同的处理策略。

另外,现在越来越多App取消了密码登录,而采用手机号+短信验证码的登录方式,我在当前的项目中也采用了这种登录方式。这种登录方式有几种好处:

  1. 不需要注册,不需要修改密码,也不需要因为忘记密码而重置密码的操作了;

  2. 用户不再需要记住密码了,也不怕密码泄露的问题了;

  3. 相对于密码登录其安全性明显提高了。

接口数据的设计

接口的数据一般都采用JSON格式进行传输,不过,需要注意的是,JSON的值只有六种数据类型:

  • Number:整数或浮点数

  • String:字符串

  • Boolean:true 或 false

  • Array:数组包含着方括号[]中

  • Object:对象包含在大括号{}中

  • Null:空类型

所以,传输的数据类型不能超过这六种数据类型。以前,我们曾经试过传输Date类型,它会转为类似于"2016年1月7日 09时17分42秒 GMT+08:00"这样的字符串,这在转换时会产生问题,不同的解析库解析方式可能不同,有的可能会转乱,有的可能直接异常了。要避免出错,必须做特殊处理,自己手动去做解析。为了根除这种问题,最好的解决方案是用毫秒数表示日期。

另外,以前的项目中还出现过字符串的"true"和"false",或者字符串的数字,甚至还出现过字符串的"null",导致解析错误,尤其是"null",导致App奔溃,后来查了好久才查出来是该问题导致的。这都是因为服务端对数据没处理好,导致有些数据转为了字符串。所以,在客户端,也不能完全信任服务端传回的数据都是对的,需要对所有异常情况都做相应处理。

服务器返回的数据结构,一般为:

{code:0msg: "success"data: { key1: value1, key2: value2, ... }
}
  • code: 状态码,0表示成功,非0表示各种不同的错误

  • msg: 描述信息,成功时为"success",错误时则是错误信息

  • data: 成功时返回的数据,类型为对象或数据

不同错误需要定义不同的状态码,属于客户端的错误和服务端的错误也要区分,比如1XX表示客户端的错误,2XX表示服务端的错误。这里举几个例子:

  • 0:成功

  • 100:请求错误

  • 101:缺少appKey

  • 102:缺少签名

  • 103:缺少参数

  • 200:服务器出错

  • 201:服务不可用

  • 202:服务器正在重启

错误信息一般有两种用途:一是客户端开发人员调试时看具体是什么错误;二是作为App错误提示直接展示给用户看。主要还是作为App错误提示,直接展示给用户看的。所以,大部分都是简短的提示信息。

data字段只在请求成功时才会有数据返回的。数据类型限定为对象或数组,当请求需要的数据为单个对象时则传回对象,当请求需要的数据是列表时,则为某个对象的数组。这里需要注意的就是,不要将data传入字符串或数字,即使请求需要的数据只有一个,比如token,那返回的data应该为:

// 正确
data: { token: 123456 }// 错误
data: 123456

接口版本的设计

接口不可能一成不变,在不停迭代中,总会发生变化。接口的变化一般会有几种:

  • 数据的变化,比如增加了旧版本不支持的数据类型

  • 参数的变化,比如新增了参数

  • 接口的废弃,不再使用该接口了

为了适应这些变化,必须得做接口版本的设计。实现上,一般有两种做法:

  1. 每个接口有各自的版本,一般为接口添加个version的参数。

  2. 整个接口系统有统一的版本,一般在URL中添加版本号,比如http://api.domain.com/v2。

大部分情况下会采用第一种方式,当某一个接口有变动时,在这个接口上叠加版本号,并兼容旧版本。App的新版本开发传参时则将传入新版本的version。

如果整个接口系统的根基都发生变动的话,比如微博API,从OAuth1.0升级到OAuth2.0,整个API都进行了升级。

有时候,一个接口的变动还会影响到其他接口,但做的时候不一定能发现。因此,最好还要有一套完善的测试机制保证每次接口变更都能测试到所有相关层面。

写在最后

关于接口设计,暂时想到的就这么多了。各位看官看完觉得有遗漏或有哪些需要优化的欢迎提出一起讨论。

摘自:http://keeganlee.me/post/architecture/20160107


注意:

token 是给用户(登录)用的,appKey/appSecret 是给 应用端(Android、iOS)用的

----------  招募未来大神 -----------------------

如果您有利他之心,乐于帮助他人,乐于分享
如果您遇到php问题,百度且问了其他群之后仍没得到解答

欢迎加入,PHP技术问答群,QQ群:292626152

教学相长!帮助他人,自己也会得到提升!

为了珍惜每个人的宝贵时间,请大家不要闲聊!

愿我们互相帮助,共同进步!

加入时留言暗号,php,ajax,thinkphp,yii...

转载于:https://blog.51cto.com/phpervip/1941175

App架构设计经验谈:服务端接口的设计相关推荐

  1. app微信支付-java服务端接口 支付/查询/退款

    app微信支付-java服务端接口 支付-查询-退款 个人看微信的文档,看了很多前辈的写法,终于调通了,在这里做一下记录. 首先来定义各种处理类(微信支付不需要特殊jar包,很多处理需要自己封装,当然 ...

  2. 移动端与PHP服务端接口通信流程设计(基础版)

    为什么80%的码农都做不了架构师?>>>    针对 --->非开放性平台 --->公司内部产品 接口特点汇总: 1.因为是非开放性的,所以所有的接口都是封闭的,只对公司 ...

  3. 全新版个人博客小程序,无需开发服务端接口即可使用

    介绍: 全新版个人博客小程序,服务端使用的是Bmob后端云,无需开发服务端接口即可使用,快速便捷,代码简洁,功能包括文章列表,文章分类列表,赞赏功能,签到,收藏文章,查看文章,点赞文章,消息通知,评论 ...

  4. 微信个人号客服系统淘宝客发单机器人sdk服务端接口列表

    微信个人号客服系统淘宝客发单机器人sdk服务端接口列表 case HeartBeatReq: {// 客户端发送的心跳包heartBeatReqHandler.handleMsg(ctx, msgVo ...

  5. RemObjects(一)客户端远程调用服务端接口过程

    RemObjects SDK 是高度封装的产物,对OOP发挥极致. 本文将以RemObjects SDK最简单的DEMO--FirstSample为例, 介绍客户端是如何完成远程调用服务端接口的全过程 ...

  6. SpringBoot 服务端接口公网远程调试,并实现 HTTP 服务监听

    前后端分离项目中,在调用接口调试时候,可以通过cpolar内网穿透将本地服务端接口模拟公共网络环境远程调用调试,本次教程以Java服务端接口为例. 1. 本地环境搭建 1.1 环境参数 JDK1.8 ...

  7. 接口-服务端接口客户端接口

    记得刚工作就开始纠结接口这个问题,纠结到现在,总算是从头到尾摸索了一遍. 首先,服务端接口,是指我这个系统作为服务,然后其他的系统来调我.首先,接口,双方会定义一定的规范,即我这个系统,和调用我这个系 ...

  8. java 全局返回码设计_服务返回码的设计

    服务返回码的设计 服务的返回码指示服务正常返回结果或是执行出现异常. 最简单的设计 返回码只有两个:成功,服务正常返回:失败,服务执行出现异常. 实际情况下,返回码只有成功和失败可能不能满足需求. 程 ...

  9. 阿里App支付服务端接口开发(含后台异步回调,退款)

    1.引入相关包文件 maven导入方式: <dependency><groupId>com.alipay</groupId><artifactId>sd ...

  10. net 服务端接口 存储,发送 app短信验证码

    net 写的app 接口,短信验证码模块的时候,本来验证码是放在session里面的,但是发现第二次会话时,愣是找不到这个验证码.于是查了下资料,不能放在session,更改为放在数据库.要求:1.验 ...

最新文章

  1. 关于素数常用结论--威尔逊定理、欧拉定理、费马小定理、米勒罗宾算法
  2. 院士 人工智能专业理解
  3. Spark启动程序:Master
  4. 服务器日志记录_5种改善服务器日志记录的技术
  5. [react] 写一个react的高阶组件并说明你对高阶组件的理解
  6. 前端大神的离逝,让我们不得不有所反思。
  7. dbforge studio for oracle,dbForge Studio for Oracle(数据库管理软件)官方版
  8. AudioScheduledSourceNode
  9. 【前端 · 面试 】HTTP 总结(十一)—— HTTPS 概述
  10. Tomcat配置监听80端口、配置虚拟主机、日志
  11. CMM术语表详细说明
  12. 网络安全学习笔记--《暗战强人:黑客攻防入门全程图解》
  13. 使用MVC结构计算梯形面积
  14. android 火车购票功能,12306 火车票订票
  15. java开发专用英语,JAVA开发常用英语词汇
  16. 微信扫码小绿盒支持支付宝+微信收款教程
  17. EasyNLP玩转文本摘要(新闻标题)生成
  18. [乱搞 树状数组] BZOJ 4548 小奇的糖果 BZOJ 3658 Jabberwocky
  19. ADS2019学习笔记:三、SPICE model导入
  20. SEO链接为什么要用nofollow,nofollow属性的作用是什么,nofollow的用法

热门文章

  1. C# 判断两个日期是否是同一天
  2. 将APP打包为IPA
  3. 数据结构之搜索算法二:二叉搜索树
  4. 煤矿行业设备管理系统
  5. hive 安装centos7
  6. HTML5 学习准备1
  7. 摘自网络上总结出的一些开源的技术
  8. js获取单选按钮选项
  9. SSM整合(spring mybatis)图书
  10. Java 中与()短路与()以及 或(|)短路或(||)的关系