I'm reading about API best practices from this document
http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api
I've built simple custom REST APIs before, and I feel I've managed to secure them, too. Before, I generated the client's authentication "token" or passport on the server, and had it printed on the page. The idea was that the client could neither guess nor easily reverse engineer how that token was generated because the function generating it was invisible to the client. This was bad UX, because the token would expire after a certain amount of time, and as a result, the page would expire and be unable to make new requests to the API.
However, I'm still unsure how this would happen on a client that had been "lightly decoupled" from the server in the sense that the web server isn't serving a page with each request. So the client needs to know something about authentication beforehand.
I sense that this pattern will force me to generate or store API authentication details on the client, which anyone can see. I find this practice to be insecure and I would like to avoid that, but given the information I know (which I admit is sparse) this is impossible.
What am I missing from this pattern with respect to API security and authentication?
You tagged your question with OAuth but you don't mention it and keep the question broad. So I find appropriate discussing the concept by showing you a very good example of storing the authentication session client-side while enforcing security at the same time with a different technology, i.e. JSON Web Token (JWT)
The basic flow works as follows:
The key point of the whole process is the token structure and its generation. Basically, the token holds the authentication state of the client. For example, it could contain the client's role.
Here, the main concern is preventing the client from forging a fake token. The technology for ensuring integrity is in place since long time and it's called HMAC. Basically, the JWT injected by the server is built as follows
header : payload : HMAC[header,payload,secret]
HMAC is a cryptographic hash which can be generated only by the entity knowing the secret. So, let's play an attack scenario.
the server validates the credentials and builds a JWT token like this
header : {
"alg": "HS256",
"typ": "JWT"
}
{
"sub": "1234567890",
"name": "John Doe",
"admin": false <--- original role
}
HS256{...}
the client tries to tamper the message as follows:
header : {
"alg": "HS256",
"typ": "JWT"
}
{
"sub": "1234567890",
"name": "John Doe",
"admin": true <--- tampered role
}
HS256{...}
but it doesn't know the secret so it cannot compute the correct HS256 code.
This is a very interesting way of letting the client storing the session while enforcing security.