Hi guys,
having worked with Engine REST API from web application (JavaScript) perspective, there
are things that could be improved to make REST API more webapp-friendly.
First of all, webapps are *not* traditional HTTP clients, i.e. they have *not* full
control over HTTP processing. There are some standard conventions and behaviors built into
web browsers that any REST API implementation should be aware of.
--
(1) Don't force clients to use cookies for transmitting authentication information!
(or don't use cookies at all)
Good explanation can be found at [
http://www.berenddeboer.net/rest/cookies.html]. Cookies
have many disadvantages:
* cookie parsing/formatting is not trivial
--> extra complexity imposed on REST clients
* in addition to Same-Origin Policy [
http://en.wikipedia.org/wiki/Same_origin_policy],
cookies can be get/set *only* for the given path
--> JavaScript running at [
http://example.com/webapp] *cannot* get/set cookies from
requests at [
http://example.com/restapi]
* cookies are the primary source of Cross-Site Request Forgery
[
http://en.wikipedia.org/wiki/Cross-site_request_forgery] attacks
--> malicious websites/scripts can forge requests to REST API that will include the
cookie, compromising user session
Alternative: clients could be given the *option* to use regular HTTP header for
transmitting authentication information.
For example, webapp could read such (sensitive information) header, store it securely via
HTML5 Session Storage [
http://en.wikipedia.org/wiki/Web_storage] and implement related
HTTP processing on its own, e.g. pass this header for all authenticated requests (instead
of pushing this responsibility to browser).
--
(2) Straight-forward HTTP Basic Auth has some drawbacks!
HTTP Basic Auth [
http://en.wikipedia.org/wiki/Basic_access_authentication] over
(non-secure) HTTP connection means sending user credentials (username/password/domain) in
easy-to-decode cleartext, i.e. the value is *not* encrypted or hashed in any way. Using
secure lower-level protocol (SSL) fixes the consequence, rather than the root cause of the
confidentiality issue.
Furthermore, browsers typically remember HTTP Basic Auth information (either via
browser-specific popup, or via XmlHttpRequest) until the browser window is closed. This
means the webapp has no control over HTTP Basic Auth header after it has been set! This is
the reason why it's hard to implement "logout" functionality in webapps when
using HTTP Basic Auth.
Last but not least, HTTP Basic Auth is vulnerable to Replay attacks
[
http://en.wikipedia.org/wiki/Replay_attack]. Someone between client and server can
intercept requests and replay them, compromising user session.
Alternative: clients could be given the *option* to use more advanced authentication
scheme.
I've just read an excellent article at
[
http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-aut...]
which describes easy yet secure authentication scheme inspired by Amazon Web Services REST
API authentication
[
http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html]. The idea is
simple: collect auth information, hash (sign) it with a private key, and send everything
to server. To guard against Replay attacks, just provide some timestamp to enforce request
expiry after some time (say, 5-15 minutes). Easy and simple!
--
(3) Support JSON for resource representations!
I think this is pretty much obvious. XML has no real advantages over JSON. JSON, on the
other hand, has good support in webapps (JavaScript) and maps directly to common data
structures (i.e. string, number, boolean, and so on).
From webapp perspective, it's much easier and natural to use JSON
than to parse/format XML documents.
Alternative: clients could be given the *option* to use JSON, in addition to XML
representation.
--
Vojtech