There are many forms to pass tokens for authentication in distributed systems. Especially, the assumption that browsers are “dumb” (or unable to keep secure tokens), makes authentication difficult.
The specs are very dense, and can be read multiple times. So, to understand what is going on, let’s use try the following example with curl:
curl http://example.com/some_action -H 'Authorization: Token token="79d4d9ee34e3f589ee94d080357afd8e"
What does this mean?
In RFC2616, there is the following definition for a HTTP header field (section 14: “Header Field Definitions”):
Authorization = "Authorization" ":" credentials
We need to look in RFC2617, to see what ‘credentials’ might be:
credentials = auth-scheme #auth-param
This can be interpreted as:
- ‘auth-scheme’ specifies an authentication method. From RFC2617, this might be ‘Token’, ‘Basic’ or ‘Digest’, but it can be ‘AWS’ too, as in the case of Amazon.
- ‘auth-param’ is the actual authentication string. This part of the header field contains the sequence that grants access or should result into a 401 (Unauthorized) response.
In cases, such as connecting two web applications, token authentication is a popular scheme. A client (= API consumer) passes a token to the server (e.g. a wrapper service for a database). The token from the request can then be used to grant access.
For example, with a Rails based RESTful service, the API authentication could look like:
def require_api_auth authenticate_or_request_with_http_token do |token, options| !(@current_user = User.where(access_token: token).first).nil? end end
Rails comes with these helpers built in (see ActionController::Metal. But there might be cases where your API (or client) is a Rack application, and it’s actually some Rack methods too that are behind the helpers above, see token_and_options. So, this check could easily be moved to Rack middleware.