REST+JSON风格的API和SOAP+XML相比,其好处是调用更加灵活,也更容易扩展,另外JSON格式传输信息比XML减少约30%的数据量,效率更高。因此在搭建API服务器时,往往首选REST风格的API。当API服务器对外提供服务时,需要一种方式来验证API使用者的权限,我们选用了当前比较流行的OAuth2认证作为例子。
2.1 本章所用到的第三方模块
Express:Web框架
js2xmlparser:将JavaScript对象转换成XML格式的字符串
faker:生成随机的测试数据
request:HTTP客户端
2.2 REST风格的API
REST架构风格最重要的架构约束有以下6个:
- 客户-服务器:通信只能由客户端单方面发起,表现为请求-响应形式。
- 无状态:通信的会话状态应该全部有客户端负责维护。
- 缓存:响应内容可以通信链的某处被缓存,以改善网络效率。
- 统一接口:通信链的组件之间通过统一的接口相互通信,以提高交互的可见性。
- 分层系统:通过限制组件的行为(即每个组件只能“看到”与其交互的紧邻层),将架构分解为若干等级的层。
- 按需代码:支持通过下载并执行一些代码,对客户端的功能进行扩展。
使用CRUD原则,只需4种行为:创建、获取、更新和销毁。与之对应的是HTTP协议的4种请求方法:POST、GET、PUT和DELETE。
2.3 定义返回数据格式
成功时,返回格式如下:
{
"status" : "OK",
"result" : 相应的结果
}
出错时,返回格式如下:
{
“status" : "Error",
"error_code" : "出错代码",
"error_message" : "详细的出错信息"
}
2.4 实现简单的API
扩展Response对象:两个方法apiSuccess()和apiError(),响应请求成功和请求失败时的结果。
2.5 关于OAuth认证
OAuth 2.0授权流程:
其中,Client指第三方应用,Resource Owner指用户,Authorization Server指我们的授权服务器,Resource Server指API服务器。
OAuth 2.0授权详解:
第1步,引导需要授权的用户到Web授权页面:https://examples.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&response_type=code&redirect_uri=YOUR_REGISTERED_REDIRECT_URI
说明:
- https://examples.com/oauth2/authorize为API服务提供方的授权页面;
- client_id为API服务提供方给当前应用分配的app_key;
- response_type为返回的授权码类型
- redirect_uri为授权成功后的回调地址,如果用户在此页面中点击了【确认授权】按钮,则API服务提供方会引导浏览器跳转到此地址,通过会在URL中加上参数code=(用于获取access_token的code)
第2步,如果用户同意授权,则页面跳转至YOUR_REGISTERED_REDIRECT_URI/?code=CODE,生成用于获取access_token的authorization_code,跳转回申请授权的应用。
说明:基于对安全的考虑,API服务提供方会对redirect_uri指定的回调地址进行检查,只有符合申请应用app_key时设置的回调地址规则才能正确显示授权页面,以免一些非法程序冒用当前应用来申请对用户的授权。
第3步,应用接收到第2步中回调的code之后,请求一下地址获得access_token:https://examples.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&client_secret=xxx&grant_type=authorization_code&redirect_uri=xxx&code=CODE.
说明:
- client_id为API服务提供方给当前应用分配的app_key,通过它来唯一标识某个应用,这个值一般是不可变的。
- client_secret为当前应用对应的app_secret,泄漏时,可以为应用设置一个新的值。
- redirect_uri为当前用于接收authorization_code的回调地址,基于对安全的考虑,API服务提供方一般要求校验此值;
- grant_type为用来换取access_token的code的类型,当有多种授权方式时才需要提供此参数;
- code为API服务提供方回调时传过来的authorization_code。
如果换取access_token成功,则返回结果格式如下:
{
"access_token" : "S1AV32hkKG", #本次授权码
"remind_in " : 3600, #有效期限制
"expires_in" : 3600
}
第4步,在成功获取到access_token后,使用获得的OAuth 2.0 Access Token调用API,一般需要带上以下两个参数:
- source,为当前应用的app_key;
- access_token,为在第3步中获取到的access_token。
定义授权接口:
2.6 实现OAuth认证
OAuth2/authorize接口:
1.功能概述:应用请求用户的授权时,需要先跳转到此页面
2.7 实现API客户端
初始化API客户端时,需要提供以下三个参数:
appKey:为API服务提供方分配的app_key
appSecret:为应用对应的app_secret
callbackUrl:为回调地址,即用户在授权页面点击【确认授权】时跳转回来的地址。
2.8 API传输过程中的安全问题
2.9 API请求频率限制
2.10 让API返回结果支持不同的格式
2.11 生成随机的测试数据