错误处理

通过http 中的状态码来表示不同的错误,如下

POST /directories
409 Conflict
{
    "status": 409,
    "code": 40924,
    "property":"name",
    "message": "A directory named 'avengers' already exists.",
    "developerMessage":"A direcotry named 'avengers' already exists, If you have a stable local cache, please expire it now.",
    "moreInfo":"http://www.example.com/docs/api/errors/40924"
}

通过http状态码来表示和已有资源名称冲突,注意,这个返回的json格式的数据里也用一个属性status表示了http状态码的数值。这样做事为了方便用户,可以直接看返回里status值,而不用时查询返回的http的状态码。
另外的问题是,http协议中只有大约17个状态码来表示客户端的出错信息,有6个表示服务器端的错误。这些有限的状态码显然不够你表示所有可能的出现的错误信息。这里的方法就是,在返回的结果里加上 code这个属性,通过code的值来定义自己的错误码。
值得注意的还有这里有两个message信息, message 和developerMessage, 区别在于,开发者(API 用户)可以直接把message信息当作返回作为他们应用给他们所开发应用的提示信息。而developerMessage, 顾名思义,是返回给开发者,帮助开发者debug用的。
另外可以通过链接给出有关自定义错误码(code)的详细信息。就像上边例子中的moreInfo属性。

安全
  1. 避过可能避免使用session,如果使用的话必须要同时使用https(SSL )
  • 不用SSL 的情况下,如果攻击者得到了session(例如通过XSS),就可以用这个session来访问,同时不用session,可以避免后端session管理的麻烦
  • 如果可能的话,验证每一次请求
  • 要保证每次请求都是无状态的
  1. 做验证的时候不要根据url来做,而是通过请求的资源。 URL在应用的生命周期中,应用是可以随意变动的
  2. 使用现成的协议:Oauth 1.0a, Oauth2, 使用http的基础验证,但要同时使用SSL(Basic over SSL only)
  3. 自定义验证协议
    需要注意的点: 要使用API key来请求,尽量避免使用用户名密码组合。
401 VS 403

这两个状态的区别是:
401 真正表示的是 Unauthentiated: 需要先提供有效凭证验证身份(然而通常返回这个状态码时,响应的响应信息都是Unauthorized)
403 表示的是 Unauthorized:你已经提供的有效凭证,但你的身份不不能访问这个资源。

服务端验证方案
  1. 服务器端对最初请求响应:

    WWWW-authenticate: <scheme name>
    realm= "Application name"
  2. 客户端提交凭证
Authorization: <scheme> <data>
API keys

原因:
1. 熵(entropy):API keys 通常比用户名密码的组合要长,这样暴力破解就更加困难,也就说用API key要比用用户名密码验证要安全.
2. 方便密码重置:如果使用用户名密码来做每次请求的验证,一旦用户重置密码,那使用用户名密码验证的应用就无法正常验证。必须使用用户名密码的应用中更改密码。使用API key就不会出现这种情况。
3. 独立: 如上一点提到的,使用API key使应用相对独立,更改密码不会影响到应用对API的访问。
4. 速度:使用API key 做校验要比用用户名密码更加有效率。因为相对安全的hash算法像 bscript 是通过正常hash的时间来阻止暴力破解的。所以,每次API 的访问都要对密码使用bscript的话,会是api的响应速度变慢。
5. 有限曝光:API key可以存储在文件中,并且设置为只要有限的用户可以读取。这样就避免了像用户名密码一样在email,通讯工具中的泄露。
6. 溯源 : 服务器端可以记录谁创建了API key等信息。

IDs
  1. IDs 应该是不透明的,客户端不必知道ID
  2. ID应该保证全局唯一 避免使用连续的数值作为ID
    a. 不安全
    b. 在集群情况下需要统一的ID生成以保证不会出现重复的ID,不方便
  3. 可以选择UUIDs, Url64 生成ID
HTTP 方法覆盖(HTTP Method Override )

可以写成这样:
POST /accounts/x7y8z9?_method=delete

ETag 可以理解成请求内容的版本号
Server (initial response): 初次访问服务器返回内容的ETag 
 ETag: “32432a5322532e532523”Client (later request) : 后续访问客户端会使用下面的HTTP头来询问版本是否匹配 
 If-None-Match: “32432a5322532e532523”Server (later response) : 如果内容没有更新,服务器返回 304 
 304 Not Modified
维护

如果需要更换域名或服务器:
1. 可以使用HTTP redirect
2. 可以创建一个临时抽象层,将访问转向到新的域名

如果数据格式需要变化:
使用设计良好的自定义的 Media type