What are the different HTTP API authentication methods?

I think this is worth a post because there is some info out there but in many cases it assumes a lot of background knowledge and the terminology is fuzzy.

Authentication (AuthN) vs. Authorization (AuthZ)

I refer to them by these abbreviated forms because I think that makes them easier to distinguish. It’s AuthN because authentication has the letter ‘n’ in it. And AuthZ because authorization has a ‘z’ in it.

In simple terms, AuthN is the process of verifying who a user is, while AuthZ is the process of verifying what they have access to.

While AuthN and AuthZ are different, it can be hard to keep them distinct in practice. Many sources use them interchangeably and inaccurately. The authentication is what (usually along with application logic and data) determines what the entity is authorized to do. To add to the confusion, the AuthN scheme is usually passed as auth-scheme to the Authorization http header with parameters referred to as authorization-parameters.

Authorization: <auth-scheme> <authorization-parameters>

Basic authentication example (credentials, encoded according to the specified scheme)

Authorization: Basic <credentials>

Most Used API Authentication Methods

These are all for http/https requests. Use of https is recommended.

In all but token authentication, AuthZ will be handled by the application looking up the permissions associated with the credentials used for AuthN. Only for token authentication, there is an option to pass permissions (scope) as part of the credentials (token) itself.

The values for most methods need to be passed in the Authorization header of the http request. But for API keys it is most common to use the x-api-key header and there are several other possibilities.

Which method should you choose?

Basic AuthN is easiest to use and least secure followed by API keys then Digest AuthN. Token authentication is most secure because the tokens are encrypted and will expire. If you want to enable SSO, Oauth is a good type of token authentication to choose.

Basic Authentication

Passes an encoded username and password with each request in the Authorization header. Encoding is usually base64. Not very secure.

Digest Authentication

Also passes an name and password in the Authorization header but more secure than basic because it uses MD5 cryptographic hashing to encrypt your password/access_token and a nonce value to stop replay attack.

GET /api/v0/tags HTTP/1.1
Host: gimmebar.com
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-us) AppleWebKit/533.6+ (KHTML, like Gecko) Version/4.0 Safari/528.16 Titanium/1.1.0
Accept: */*
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Authorization: Digest username="funkatron", realm="GimmeBarAPI", nonce="7a3ab1f9cde605f27797cd04c4d1fcf6", uri="/api/v0/tags", response="3654f9b1b2ba9489e1f01ae792852987", opaque="94619f8a70068b2591c2eed622525b0e", algorithm="MD5", cnonce="6897ccbff3b08776ab61e69a814c05b4", nc=00000001, qop="auth"
Connection: keep-alive

Token Authentication aka bearer token

Set the Authorization header in the http request like so:

Authorization: Bearer <token>

If you have (bear) the token, you can get the appropriate access to the API.

The token is a string that represents the user’s identity and permissions e.g. scope. You don’t have to pass a scope. You can also implement your app to use the token to look up proper permissions. You can combine passing scopes and doing permission lookup in the app.

This is more secure because the token is encrypted and has a limited lifespan you can configure.

OAuth authentication

OAuth is an open authorization framework that uses a type of token authentication, but it leverages credentials from one service provider to provide SSO (Single sign-on) access to other service providers.

API key authentication

API keys can be used for authentication and authorization. They do not expire which creates some security risk.

There are several places where API keys can be passed in a HTTP request.

The most popular API key location for modern APIs is in headers.

x-api-key

The most popular choice for including API keys in headers, perhaps due to its usage by AWS API Gateway, `x-api-key` is a custom header convention for passing your API key.

GET / HTTP/1.1
Host: example.com
X-API-KEY:  abcdef12345

API key passing via Basic Authentication

You can pass the API key via Basic Auth as either the username or password. Most implementations pair the API key with a blank value for the unused field (username or password).

GET / HTTP/1.1
Host: example.com
Authorization: Basic bWFnZ2llOnN1bW1lcnM=

You will need to base64-encode the `username:password` content, but most request libraries do this for you.

API key passing via Bearer Authentication

Some APIs use the `Authorization` header to handle the API key, usually with the Bearer keyword. This method is also used for other tokens, such as those generated by OAuth.

The client must send this token in the `Authorization` header when making requests to protected resources:

Authorization: Bearer abcdef12345

Non-header API Key Locations

Though the header has become the preferred location for API keys, there are non-header methods still used by many APIs.

API Key in Query String

A popular method for early APIs, passing an API key through a query string in a URL is certainly easy. However, this method can risk API key exposure since, despite encryption, the parameters can be stored in web server logs.

curl -X GET "https://example.com/endpoint/?api_key=abcdef12345"

If you use the query string method, you’ll want to make sure that there’s a low risk of the API key being shared.

API key in Request Body Parameter

Another method seen, especially in older APIs, is to pass an API key in the POST body as JSON:

curl -X POST
	`https://example.com/endpoint/’ 
	-H ‘content-type: application/json’ 
	-d ‘ {
		“api_key”: abcdef12345”
	}’

The most significant drawback to this method is that authentication is mixed in with other data.

Sources

https://konghq.com/blog/engineering/api-authentication-vs-api-authorization

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization

https://stackoverflow.com/questions/8483717/digest-basic-and-bearer-authentication

https://blog.stoplight.io/api-keys-best-practices-to-authenticate-apis

Leave a comment