良好接口实践
安全性
采用 https
创建appid,appkey和appsecret
-
appid:应用的唯一标识
-
appkey:公钥=账号
-
appsecret:私钥=密码
-
设计一个认证系统,专用于创建第三方接入应用的账号信息,用于生成appid,appkey和appsecret,然后发appkey和appsecret给第三方接入应用,用于做认证
-
第三方接入应用自行注册,需要校验企业信息合法性
Token:令牌(过期失效)
- 第三方接入应用获取第一步中的appkey和appsecret
- 请求认证系统获取nonce随机数,服务端在缓存中存放下nonce
- 客户端拿到这个随机数后将其与appsecret拼接生appsecretStr,然后调用生成签名方法,传入appsecretStr,appkey,nonce,url(备注:可转大写,转小写,追加特殊字符,然后加密)进行非可逆加密(MD5/SHA1等),生成签名A。接着构造请求把签名放到请求头signature,post请求体中放入参数:appkey,nonce,timestamp,url根据request.getRequestURI()获取,调用认证接口
- 认证系统获取请求后,查询根据appkey查询缓存中的nonce,判断是否存在,不存在则提示不合法请求;判断是否相等,不等则为恶意请求。
判断timestamp的时效性,防止恶意请求:数据包中的客户端时间戳字段,然后用服务器当前时间去减客户端时间,看结果是否在一个区间内。
先根据appkey查询数据库,判断是否存在,如不存在则提示不合法用户;反之,查出appsecret,按照客户端的签名加密方式,进行加密,生成签名B,比较A和B,如果一样则生成token,失效缓存中的nonce,返回token。
使用 Post 请求 ?
客户端 IP 白名单 (可选)
单个接口针对IP限流(令牌桶限流,漏桶限流,计数器限流)
限流是为了更好的维护系统稳定性。使用redis进行接口调用次数统计,ip+接口地址作为key,访问次数作为value,每次请求value+1,设置过期时长来限制接口的调用频率
数据合法性校验
密码查询(加缓存,key使用客户号)
- 密码更新时,更新redis;
- 缓存查不到,查数据库,同时更新缓存;
- 密码在缓存和数据库都需要加密,返回时才解密(或者是返回客户端时,客户端自行解密)
接口调用失败告警
高可用:服务器集群部署(2-3)
客户端重试机制
变更轨迹,保存上次密码?
查询密码和交易密码是否分两条?
幂等性
幂等性是指任意多次请求的执行结果和一次请求的执行结果所产生的影响相同。说的直白一点就是查询操作无论查询多少次都不会影响数据本身,因此查询操作本身就是幂等的。但是新增操作,每执行一次数据库就会发生变化,所以它是非幂等的。
幂等问题的解决有很多思路,这里讲一种比较严谨的。提供一个生成随机数的接口,随机数全局唯一。调用接口的时候带入随机数。
第一次调用,业务处理成功后,将随机数作为key,操作结果作为value,存入redis,同时设置过期时长。
第二次调用,查询redis,如果key存在,则证明是重复提交,直接返回错误。
- 查询与删除操作是天然幂等
- 唯一索引,防止新增脏数据
- token机制,防止页面重复提交
- 悲观锁 for update
- 乐观锁(通过版本号/时间戳实现, 通过条件限制where avai_amount-#subAmount# >= 0)
- 分布式锁
- 状态机幂等(如果状态机已经处于下一个状态,这时候来了一个上一个状态的变更,理论上是不能够变更的,这样的话,保证了有限状态机的幂等。)
- select + insert(并发不高的后台系统,或者一些任务JOB,为了支持幂等,支持重复执行)
- redis存储订单号,如果已存在的话说明已经处理过
数据规范
版本控制
一套成熟的API文档,一旦发布是不允许随意修改接口的。这时候如果想新增或者修改接口,就需要加入版本控制,版本号可以是整数类型,也可以是浮点数类型。一般接口地址都会带上版本号,http://ip:port//v1/list。
响应状态码规范
统一响应数据格式
为了方便给客户端响应,响应数据会包含三个属性,状态码(code)、信息描述(message)、响应数据(data)。客户端根据状态码及信息描述可快速知道接口,如果状态码返回成功,再开始处理数据。
单点登录
— 同域下的单点登录,只需共享session即可。 — 登录业务系统,跳转至SSO服务器,判断用户名密码正确,在sso域下种下cookie,在session中标记为登录,返回一个ticket,跳转到业务系统,业务系统再拿这个ticket跑去SSO服务器验证ticket是否有效,有效的话,在业务系统session中设置为已登录即可。 — 相比于单系统登录,sso需要一个独立的认证中心,只有认证中心能接受用户的用户名密码等安全信息,其他系统不提供登录入口,只接受认证中心的间接授权。间接授权通过令牌实现,sso认证中心验证用户的用户名密码没问题,创建授权令牌,在接下来的跳转过程中,授权令牌作为参数发送给各个子系统,子系统拿到令牌,即得到了授权,可以借此创建局部会话,局部会话登录方式与单系统的登录方式相同。这个过程,也就是单点登录的原理,用下图说明 — 单点登录自然也要单点注销,在一个子系统中注销,所有子系统的会话都将被销毁,用下面的图来说明