How to implement secure REST API authentication over HTTP
Important: this post is not a complete and expert guide on API security. It is mainly done to test Postman Pre-request hook that is described in Introduction to Postman with examples post. It does not go into all the details about API security, SSL certificates, encrypting the data, etc. It gives basic information how you can protect your API’s consumers against their network traffic being sniffed and credentials, apiKeys, session keys, etc stolen.
Authentication vs. Authorisation
Authentication is defined as "Who you are". It deals with usernames and password. The authorization is defined as "What you can do". It deals with permissions. Before dealing with permissions application must know the user, so Authorisation comes after Authentication.Basic Authentication
As it is stated it is very basic. The idea is to send a Base64 encoded username and password in the header of the request in the following format:Authorization: Basic dXNlcjpwYXNz
Server decodes the username and password and uses them to authenticate and authorize the user. Problem with Basic authentication is it must be used only over HTTPS since network traffic is encrypted. Over HTTP request can be easily sniffed. Base64 is reversible and there are numerous tools on the web where you can put dXNlcjpwYXNz and they will return user:pass as plain text.
Nota bene: Never use this one without HTTPS.
OAuth and OAuth 2.0
OAuth is authorization protocol. It is intended mainly for web but can be used in API authorization. The idea is that authentication and authorization are done by a third party like Microsoft, Google, Facebook, Twitter, etc. This is easy for API as it does not have to deal with user data. Customer logins to the third party and then access token is being issued. Token has some validity which is not too long, but not too short, usually 1 or 2 days. The API can obtain user details from the third party by this token. The user authenticates itself to the API with this access token by sending it in the request header:Authorization: Bearer 66408bd9-2bc0-40c3-9823-e9bec390532a
Problem with OAuth is it also must be used over HTTPS. Over HTTP traffic can be sniffed and the token can be stolen. Although token has some expiry time, it is long enough for a hacker to use API on your behalf.
Nota bene: Never use this one without HTTPS.
API keys
API keys have become the standard when consuming an API. API key is some random hash which uniquely identifies the consumer. API keys have numerous benefits over username/password mechanism. Again in case of HTTP network traffic can be sniffed and API key can be stolen.HTTPS
Reading post so far turned out there is not a single API authentication protocol that is secure if not used over HTTPS. In the current post, a solution is proposed. It is commonly used in public APIs, it is possible to exist as a standard I'm just not aware of its name, which provides secure API authentication even over HTTP.Implement API security over HTTP
In short, in order to have security over HTTP following steps should be done:- The secret key that is known only by API consumer and API provider is needed along with API key.
- The secret key is used to one way hash a token which is sent to the server along with API key in the API call.
- Token consists of API key + Secret key + Current time in seconds, which then gets hashed with SHA-256 algorithm preferably.
- Server recreates all the tokens locally for every second for some time in the future, preferably not too long - 30~120 seconds.
- Server recreates all the tokens for 30~120 seconds in the past, to take into account the time needed for the request to reach the server.
- The server compares each of the tokens with received one.
- If there is match consumer is authenticated and a response is returned.