You probably know that HTTP is a bridge between the client and the server (transport protocol). And it is a stateless protocol (stateless protocol).
So, what is stateless? Explain easily, a stateless protocol is the protocol after the client sends data to the server, the server completes, returning the results to the client, the “relationship” between the client and the server is “severed”. , the server does not save any state data of the client.
To explain by example, this means that if we are logged into the Facebook account. After we move to the Settings page, we will have to log in again because the server does not keep our status. However, this problem has been solved with sessions and cookies. By storing information on both the client and the server via session and cookies, the server can tell if the client is logged in or not.
Apart from Session and Cookies, there are still a few other techniques used to authenticate login. Including JWT.
1. What is JWT?
– JWT stands for “JSON Web Token” – an open standard (RFC 7519) for securing data transmission between endpoints.
A JSON Web Token (JWT) is a JSON object that is defined in RFC 7519 as a safe way to represent a set of information between two parties. The token is composed of a header, a payload, and a signature.
– I temporarily translate: –
JWT is a JSON object defined in RFC 7519 standard as a secure way to exchange information between two parties. And the token includes a header, a payload and a signature.
JSON Web Token consists of 3 parts, separated by dots (.), Which are:
– This is where the information is used to answer the question: “How is the JWT code calculated?”
For example, for a Header, it is a JSON object like this:
– In the Header example above:
- The “typ” (short for type) is the Token type, here is the JWT.
- And “alg” (short for algorithm) is a hash algorithm that creates a signature for Token, in the example above HS256 is an algorithm named HMAC-SHA256, a hashing algorithm that uses the secret key (Secret Key) to calculate Math creates signatures.
– This is where the data we want to save in JWT.
For example, I want to save some information of the user on the token, like this:
"occupation": "Full stack web developer",
// standard fields
"iss": "Trong Nhan",
In the above example, I saved 3 information of the user when the login was successful, that is id, name and occupation, of course you can save as much as you want.
- There are 2 notes when defining payload:
- Without password, the information that needs to be secured into the payload may be decode
- Do not put too much information in the payload because it will create a delay for the server
Also note for yourself the 3 schools I put below the Standard Fields line, they are the standard fields, is optional means you can create or not, but should create offline because it will be useful.
– “iss” stands for Issuer is the information that created the Token (not the user, but it is the name of your backend system for example)
– “iat” stands for Issued at, is the time stamp when the token was created.
– “exp” stands for Expiration time, determines the expiry time of Token
There are also many other standard fields, please refer here, see which one is suitable for your application. https://en.wikipedia.org/wiki/JSON_Web_Token#Standard_fields
Check out the fake code below and then I will explain in detail about the implementation of this signature:
// signature algorithm
const data = base64urlEncode(header) + “.” + base64urlEncode(payload);
const hashedData = Hash(data, secret);
const signature = base64urlEncode(hashedData);
– First, we will Encode (convert) the 2 Headers and Playload above according to Base64URL Encoder, and concatenate the two received strings (separated by dots “.”) And assign it to a variable as data.
– Next will Hash (hashing) that data with “alg”, it is the signature creation algorithm that we have defined above Header (HS256 – HMAC-SHA256) with a secret string (this secret string will are set by the developer of each project and make sure not to expose this string, which can be included in the ENV environment variable.)
– After hashing above, execute Encode again that hash data as Base64URL Encode, and we will get the signature “Signature”.
– After having all 3 components HEADER, PAYLOAD, SIGNATURE, what to do? This step is especially important, that we will combine the three components and separate them by dots according to the standard structure of JWT:
More specifically, I will describe by this fake code:
const headerEncode = base64urlEncode(header); // ví dụ kết quả: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
const payloadEncode = base64urlEncode(payload); // ví dụ kết quả: eyJ1c2VySWQiOiJiMDhmODZhZi0zNWRhLTQ4ZjItOGZhYi1jZWYzOTA0NjYwYmQifQ
const data = headerEncode + "." + payloadEncode;
const hashedData = Hash(data, secret);
const signature = base64urlEncode(hashedData); // ví dụ kết quả: xN_h82PHVTCMA9vdoHrcZxH-x5mb11y1537t3rGzcM
// cuối cùng thì mã JWT theo đúng cấu trúc header.payload.signature sẽ trông như sau:
const JWT = headerEncode + "." + payloadEncode + "." + signature;
// Kết quả:
In addition, you can also quickly create a JWT code with the online tool here: – https://jwt.io/
2. How does JWT protect our data?
The answer is: JWT does not protect your data.
– The important purpose that you need to know is that JWT is not hidden, does not obscure, does not hide data at all, but it is used to prove that the data is generated by an authentic source.
– You can look back at the steps of handling Header, Payload, Signature above, the data is only Encoded and Hash (Signed), not Encrypted.
“Note: I have to keep the above words in English because Encoded and Encrypted translated into Vietnamese are both” Encryption “but their meanings are completely different.”
Also you can refer to the following 2 links to understand more about the difference between Encoded and Encrypted:
So then you will be wondering: “What if an attacker in the middle (Man-in-the-middle) captures a packet containing JWT code and then they decode and retrieve the user information?”
The answer is: “yes, it is possible, so always make sure that your application must have HTTPS encryption protocol.”
3. How does the server authenticate JWT code from client?
– In the above section, please look back for yourself that when creating JWT code, we have to use a secret string “Secret” in the step of creating a signature (signature). This “secret” string is unique to the application and must be carefully prioritized for secure storage on the server side.
– When receiving the token sent from the client, the server will take the Signature (signature) inside the token, and verify (check) whether the signature received is correct to be HASH (hashed) by same algorithm and string “Secret” as above or not.
– And finally, obviously, if the client’s signature matches the signature generated from the server, then that JWT is valid, otherwise not, and the Backend API programmer like us will Depending on the circumstances, the response to the client is reasonable.
4. Mechanism to log in with Session and Cookies (Session-Based Authentication)
– With this mechanism, after logging in, the server will create a session for the user and save it somewhere (be it file, memory, database, …). A session ID will then be stored in your browser’s cookies. While the user accesses the website, that session ID will be retrieved by the browser and included in the request. This way, the server can refer to the session saved on the server to see if this user is logged in or not. After the user logs out, the session is deleted.
5. Authentication mechanism of logging in with Token – (Token-Based Authentication)
– When referring to the login authentication mechanism with Token (Token-Based Authentication), most people often refer to JWT. Previously, websites only used Session and Cookies mechanism, but now Token mechanism is extremely popular and gradually becomes a standard for login authentication.
– What is the mechanism of JWT? When the user logs in, the server generates an encrypted token and sends it back to the client. When the token is received, the client stores it in memory (usually local storage). Then, every time the client requests to the server, it will send a token. From this token the server will know who this user is.
“For storing JWT in the client, there will be some cases, if it is a web browser, JWT can be saved to Local Storage, IOS app will be Keychain and Android app will be saved to SharedPreferences.”
What should be used?
Authentication by JWT is a method that I think will become a standard in the future to gradually replace Session, Cookies when SPA is becoming a trend. Also it can scale better than Session Cookies because the token will be stored on the client side while the Session must be stored on the server and this can be a problem when a large number of users use the same system. at.
One downside to JWT, however, is that it is much larger than the session ID because JWT contains more user information. In addition, we need to be careful about adding user information to JWT because it can be decode.