Basic Auth
Session Based Auth
Token Based Auth
API Key
Bearer Token
JWT
OAuth 2.0
Authentication deals with the identity of the user: The “Who are you?” part. Prove identity using passwords.
Authorization deals with the access of resources for a user: The “Can you access that?” part. Follows authentication.
Authorization: Basic <"username:password" encoded in base64>
Server checks for Authorization
header and if not present or invalid credentials, it sends back www-authenticate
header (a prompt is shown in the browser to input credentials).
The client then sends username:password
encoded in base64 in Authorization: Basic r4Dl3tFaXffsdfsvSse3=
header and it is decoded and credentials are verified on the server. The server either sends 401 Unauthorized
again or 200 OK
.
In APIs, there is no prompt so it acts like a simple API key. Always use HTTPS/TLS with it.
A random unique identifier called session token (aka session ID) is generated and stored on successful login onto the server and shared back with the client. Client also stores it in either cookies or local storage (if cookies are disabled). The client has to send that token in every subsequent request.
Often uses cookies since storage on client and sending in subsequent request is to be done.
On every request, the server checks if session is still valid for that user. When the user logs out, the session id gets deleted from the server and subsequently the client, and that session id is never used again.
Always use HTTPS/TLS in conjunction with token based authentication mechanisms since tokens can be visible to everyone.
Tokens are usually generated on and fetched from the server (using another auth mechanism like username and password) and sent in subsequent requests. They have an expiration time and must be fetched again (refreshed) after that time has passed otherwise they become invalid and server returns a 401
as response status code.
Client stores the token. Server doesn’t store the token (stateless)
Tokens are normally signed with a secret to identify any tampering
Provide API key in a custom header (e.g. X-Api-Key
) to users and include that in requests and it is verified by the server.
API-key can be present anywhere in header, cookie, query param, body, etc…
Authorization: Bearer <token_string>
Bearer tokens come from OAuth 2.0 specification but they can be used in a standalone way. Bearer tokens don’t have a particular meaning unlike Basic tokens.
Just like the other token based strategies but only differentiator is that the token structure is standardized here.
header.payload.signature
header = base64(tokenMeta)
payload = base64(claims)
signature = HMAC_SHA256(header.payload, SECRET)
// tokenMeta
{
"typ": "jwt",
"alg": "H256"
}
// claims (in this example: 2 custom public + 2 registered)
{
"userid": "XDF-11",
"email": "johndoe@gmail.com",
"exp": "1592427938",
"iat": "1590969600"
}
// SECRET - server stores it, used to generate a symmetric key for HMAC algorithm to create and verify signature part of JWT token
The signature (anti-tampering measure) proves that the token is received as-is (as server generated it) from the client and the username and expiration date present in it are correct. So token verification in JWT boils down to just checking the signature validity and then we can extract payload (claims) and identify user and their access rights from that info.
Authorization: Bearer <jwt_token>
HTTP headerPros: lightweight, stateless, standalone as no token store is required on the server-side.
Cons: since its standalone, the token has full authority. This means that if anyone gets their hands on the token they can impersonate us till it expires, and revoking tokens isn’t easy (see tips below).
Refresh Tokens: JWT tokens can be refreshed if the client sends the security server a Refresh Token. The server initially sends both the Access Token and a Refresh Token to the client at the time of token creation and issue. The client stores the refresh token securely, often in a secure HTTP-only cookie or local storage. It can then use it later to get another access token without terminating the session.
Some Tips and Pointers:
References:
Used to get a token from a third party server in order to access its resources.
Our app sends a request to the authorization server (often the same as resource server) and it decides whether to give access to the requested resources and sends a token back if access is granted. This token can be a JWT Bearer token.
Ex - using Google account to sign-in to GitHub - GitHub triggers Google sign-in page and Google authenticates the user (on sign-in) and then asks if we want to share info with GitHub, if we allow we get a token from Google that GitHub uses to talk to Google in order to access user info.
In the above example, we have used OAuth to authenticate user for GitHub, but beneath the surface OAuth is always about Authorization. We have authorized GitHub to use our info from Google.
Four types of authorization flows (aka grant types) for generating a token:
The token we get back has an expiry date-time and accompanied by a refresh token that we use to refresh the main access token when it expires. We simply send the refresh token to auth server and get a new access token back.