A lot of examples about RESTful Web Services do not take into account the problem that today many applications are multi-user.
Imagine a multi-user backend exposing a RESTful API. The backend data architecture uses a shared database and shared schema. Each table will contain a reference to a tenant_id
:
+-------------+----+-----------------+
| tenant_name| id | shared_secret |
+-------------+----+-----------------+
| bob | 1 | 2737sm45sx543 |
+-------------+----+-----------------+
| alice | 2 | 2190sl39sa8da |
+-------------+----+-----------------+
+-------------+----+-------+-----------+
| pet_name | id | type | tenant_id |
+-------------+----+-------+-----------+
| fuffy | 1 | dog | 1 |
+-------------+----+-------+-----------+
| kerry | 2 | cat | 2 |
+-------------+----+-------+-----------+
Question 1: with three or more client applications (i.e Android, iOS and Web App) interacting with the RESTful backend, how would you perform authentication against the backend?
RESTful backend, API, HTTP-Verbs, shared database and schema
|
|
+---- Web Application (Client 1)
| |
| + Alice
| |
| + Bob
|
+---- Android Application (Client 2)
| |
| + Alice
| |
| + Bob
|
+---- iOS Application (Client 3)
| |
| + Alice
| |
| + Bob
|
Each client should allow Alice and Bob to manage her/his pets. Each client is a GUI, and it's going to use (internally, making HTTP requests) the backend. Question: how can each client can authenticate against the backend?
Assume HMAC (it's perfectly RESTful, no sessions): this method involves signing the payload with a shared secret (never sent over the wire). Should each client have its own copy of the tenant
table (which holds the shared_secret
field)?
Android App -> Client Sign -> Signed Request -> Backend -> Result
Web App -> Client Sign -> Signed Request -> Backend -> Result
Question 2: what should the resource URI's look like?
Here are two possibilities for ways to GET Bob's pets:
Possibility #1: The Authorization
header gives you the tenant's (unique) name:
GET /pets HTTP/1.1
Host: www.example.org
Authorization: bob:c29kYW9kYSBhb2lzYWRoIGYgZDUzNDUz
Possibility #2. The tenant_id
is sent as query parameter:
GET /pets/tenant_id=1 HTTP/1.1
Host: www.example.org
Authorization: bob:c29kYW9kYSBhb2lzYWRoIGYgZDUzNDUz