Authentication and session management in APIs
How we will learn about JSON Web Tokens. One of the main characteristics of APIs is their statelessness, or by its English term: of being stateless.
What does this mean? Well, every time a request is received, the state has to be recreated, including the user's session and authentication.
It may seem cumbersome and unnecessary, but the fact that being stateless is the main feature that allows us to distribute our API on numerous servers without the need to have the sessions persisted in a distributed manner, which is an unnecessary hassle.
Obviously, what we cannot do is to ask the user to authenticate with every request to the API, as this would be a disastrous user experience. For this the most common solution is to use an authentication system based on tokens. Let's look at a couple of examples:
JWT Tokens
The acronym JWT stands for JSON Web Tokens, and, as their name indicates, they are some tokens based on JSON. It is in fact an open standard that defines a compact and self-contained way to securely transmit information between backend y frontend in the form of a JSON object. It is secure because this information can be verified and trusted as it is digitally signed. The tokens JWT can be signed using the algorithm HMAC or by means of a system PKI of public and private keys based on RSA o ECDSA.
Optionally, these tokens can be encrypted to hide the information during transmission between both parties. The signature of the token allows the integrity of the information contained in it to be verified, and by using public and private keys, guarantees that only the holder The private key has been able to issue this information.
Let's look at an example of a token JWT:

As can be seen, there is a structure of three elements separated by dots, as follows:
xxxxxxxxxx.yyyyyyyyyyyyyyyy.zzzzzzzzzzzzzzzz
Each of these sections, encoded in base64, are respectively:
- Header
- Payload (Body)
- Signature
By decoding each of these elements we can see the contents of the header and the body (the signature is not encoded):

Header
Usually the header is composed of two elements: the type (typ) which in this case is always JWT, and the algorithm used to verify the signature.
Payload
The body, on the other hand, is composed of a series of attributes (or claims) registered (sub, iss, exp, iat...) private (admin) and public (name).
The list of claims registered can be consulted in the official specification. They are usually composed of only three letters, since it is assumed that the token must be compact. Let's take a look at some of them:
- iss: issuer or who has issued the token.
- sub: subject or the reason for the issuance of the token.
- exp: expiration, the date on which the token. Usually in the form of timestamp.
- iat: issued at, the date on which the token. Usually in the form of timestamp.
- aud: audience, the target audience token.
Usually the claim most commonly used is the exp, In many cases the rest are irrelevant, but the expiration date is always important.
The claims private are all those that we want to include: name, email, id... everything we need.
The claims public can be defined by JWT users, but to avoid collisions these must be registered in the JSON Web Tokens IANA Registry.
Signature
Verifying the signature is as simple as using the private key to sign that header/body pair, and checking that it matches the one sent to us to ensure that the signer is in possession of the private key to sign.
Token usage
After logging in with the API, it returns a token similar to the one we have seen before, the way of using these tokens is to include them with the header Authorization in this way:
Authorization: Bearer eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.jYW04zLDHfR1v7xdrW3lCGZrMIsVe0vWCfVkN2DRns2c3MN-mcp_-RE6TN9umSBYoNV-mnb31wFf8iun3fB6aDS6m_OXAiURVEKrPFNGlR38JSHUtsFzqTOj-wFrJZZN4RwvZnNGSMvK3wzzUriZqmiNLsG8lktlEn6KA4kYVaM61_NpmPHWAjGExWv7cjHYupcjMSmR8uMTwN5UuAwgW6FRstCJEfoxwb0WKiyoaSlDuIiHZZJ0cyGhhEmmAPiCwtPAwGeaL1yZMcp0p82cpTQ5Qb-7CtRov3N4DcOHgWYk6LomPR5j5cCkePAz87duqyzSMpCB0mCOuE3CU2VMtGeQ
The keyword Bearer indicates that it is a self-contained token. As long as the token is valid (the exp contains the expiration date) the API will give us access to the logged in user's session.
Refresh Tokens
Typically the TTL (time to live) or duration of the token, is relatively short, since anyone who has the token could impersonate the session. The problem is that we can't keep asking the user to authenticate every now and then, so we have to be creative and find an alternative.
The preferred alternative is the use of the refresh token. The refresh token is a token which allows us to obtain a new token without having to re-enter the user's credentials. Normally the refresh token has a much longer life than that of the token session, and it is the responsibility of the frontend store it in the safest possible way.
In contrast to the tokens session, these are stored in the database and can be manually overridden, so if we are aware or suspect that there has been a theft of the session, we will be able to manually override them. token, we can invalidate them and leave the attacker unable to continue using it.
In addition to this, we can take extra precautions, such as associating it to a specific IP or any other measure we deem appropriate.
Basic Auth
This is a strongly discouraged form of authentication, as it involves temporarily storing the user's password for authentication purposes.
Basically, it consists of coding in base64 of the user's name and password, separated by the colon character and send it in the header Authorization.
Suppose the user is ad***@*********re.com and the password p4ssW0rD then the string to be encoded would be:
ad***@*********re.com:p4ssW0rD
It would result in:
YWRtaW5Ac2VjdHVyZS5jb206cDRzc1cwckQ=
And we would use it in this way:
Authorization: Basic YWRtaW5Ac2VjdHVyZS5jb206cDRzc1cwckQ=
In this case the keyword Basic would indicate the type of authentication.
As you can see, it is very easy for a potential attacker to esnife the traffic and obtain our user's password with a simple decoding of the token.
Conclusion
When dealing with stateless APIs we need to make use of some method to recreate the user's session. Currently there are several alternatives. Here we have seen two, but we only recommend the use of JWT, since it is an open standard, focused on security and data integrity and widely used in production.
Basic authentication is just a remnant of bygone eras that is doomed to disappear, as it is totally insecure.
Secture encourages you to leave comments explaining what other means you use to monitor your API user sessions!
_ Bibliography:
JSON Web Tokens (JWT)
Basic Access Authorization
