Table of contents
- What is authentication?
- Types of authentication
- Authentication flow
- Session-based vs token-based authentication
- Where to store tokens and session ID on the client side?
- JSON-Web Token: an example of token-based authentication
- JWT example: analyzing ChatGPT login mechanism
- Auth0 quick overview
- Summary
- References
In the digital age, the need for secure and reliable authentication has become more important than ever. Authentication is the process of verifying the identity of a user or system, ensuring that they are who they claim to be. This can be achieved through various methods, such as passwords, biometric data, or security tokens. In this article, we will explore the different types of authentication and their use cases, including session-based and token-based authentication. We will also examine where to store tokens on the client side and common attacks that can compromise authentication. Additionally, we will take a closer look at JSON Web Tokens (JWTs), their flow, and structure. To illustrate these concepts, we will analyze the authentication mechanism used by ChatGPT, an AI language model, as an example of JWT. Finally, we will provide a quick overview of Auth0, a popular third-party authentication provider. By the end of this article, you will have a solid understanding of authentication and how to implement it securely in your own applications.
What is authentication?
Definition
Authentication is the process of verifying the identity of a user or system attempting to access a particular resource or service. It is a fundamental aspect of computer security that helps to ensure that only authorized individuals or entities have access to sensitive information or functionality.
Authentication vs authorization
Authentication is the process of verifying the identity of a user or a system. It involves providing credentials, such as a username and password, and confirming that they are valid. Authentication ensures that the user or system is who they claim to be, and it is typically the first step in any security process.
Authorization, on the other hand, is the process of determining whether an authenticated user or system has the necessary permissions to access a particular resource or perform a specific action. It involves checking the privileges and rights of the user or system, and deciding whether they are allowed to proceed. Authorization is typically the second step in a security process, following authentication.
Types of authentication
Authentication is the process of verifying the identity of a user or entity. It can be achieved through one or more factors, including:
Something you have
Something you are
Something you know
Something you have could be a physical device, such as a smart card or a mobile phone, that generates a one-time password or a digital certificate that proves your identity. Something you are refers to biometric information, such as fingerprints or facial recognition, that can be used to authenticate users based on their unique physical characteristics. Something you know could be a password, a PIN, or answers to security questions that only the user would know. For example, when logging into a bank account, the user may be required to provide a password (something they know) and use a physical device, such as a security token (something they have), to generate a one-time password. Another example is using fingerprint recognition (something you are) to unlock a mobile phone.
Authentication flow
Authentication is the process of verifying the identity of a user or system, and it is typically composed of a series of steps that constitute its normal flow. The normal flow of authentication often begins with the user providing some form of identification, such as a username or email, and a secret, such as a password or PIN. The system then checks whether the provided credentials match the stored credentials associated with the user's identity. If the verification is successful, the system generates a token or session that the user can use to access the protected resources or services. This token or session is then validated on subsequent requests to ensure that the user remains authenticated throughout their session.
Session-based vs token-based authentication
Session-based and token-based authentication are two common methods used to secure web applications. While they both serve the same purpose, they differ in terms of how they operate and the benefits they provide.
Session-based authentication involves creating a session on the server for each user who logs in, and then using cookies to store the session ID on the client-side. The server uses the session ID to authenticate the user for each subsequent request. This type of authentication is commonly used in web applications that require users to be logged in for an extended period, such as social media platforms, online banking, or e-commerce websites.
Pros:
Simplicity: Session-based authentication is relatively simple to implement and requires less technical knowledge.
Revocability: Sessions can be easily revoked on the server, which is useful when a user logs out, or if the session becomes compromised.
Security: Session data is stored on the server-side, which makes it more secure.
Cons:
Scalability: Session-based authentication can be challenging to scale when the application has a large number of users.
Performance: Storing session data on the server can lead to additional load, which can affect performance.
Stateful: Sessions are stateful, which means they require additional server resources to manage user state.
Token-based authentication involves creating a token that represents a user's identity, and then sending the token to the client-side. The client sends the token with each subsequent request, and the server uses the token to authenticate the user. This type of authentication is commonly used in modern web applications that rely on APIs, such as mobile or single-page applications.
Pros:
Stateless: Tokens are stateless, which means they do not require additional server resources to manage user state.
Scalability: Token-based authentication is easy to scale since tokens can be validated without requiring server-side storage.
Flexibility: Tokens can be used across multiple platforms and APIs, making them a popular choice for modern web applications.
Cons:
Security: Token-based authentication can be less secure if tokens are not implemented correctly.
Complexity: Implementing token-based authentication requires a good understanding of security concepts and may require additional infrastructure.
Revocability: Revoking tokens can be challenging, especially when tokens are used across multiple platforms or APIs.
In summary, both session-based and token-based authentication have their pros and cons, and the choice between them depends on the specific requirements of the web application. Session-based authentication is simpler and more secure, while token-based authentication is more flexible and scalable.
Where to store tokens and session ID on the client side?
In session-based authentication, the session ID is typically stored in a cookie on the client side. In token-based authentication, the token is usually stored in the client-side storage, such as LocalStorage or SessionStorage. These are both mechanisms that allow web applications to store data on the client's device.
LocalStorage allows web applications to store data with no expiration date, while SessionStorage allows data to be stored for the duration of the session (until the browser is closed). Both LocalStorage and SessionStorage can be accessed only by the web application that created the data, making them a relatively secure way to store tokens.
However, it is important to note that storing tokens on the client-side can pose security risks, as an attacker can potentially access and steal the token, thereby gaining unauthorized access to the user's account. Therefore, it is important to take proper measures to secure the storage of tokens, such as encrypting the tokens and implementing measures to prevent cross-site scripting (XSS) attacks.
JSON-Web Token: an example of token-based authentication
JWT is an example of token-based authentication. As mentioned before, the main difference between token-based and session based-authentication is that token-based authentication is stateless i.e. does not need to store information about the token on the server side. Information about the user is stored in the token itself and encoded and then decoded on the server side to retrieve the information again. Before digging deeper into the structure of JWT, let’s see a simple example of the user flow:
A user logs in using their email and password
The server validates the credentials and uses the user’s information to generate a token and responds with the token to the user
On the client side, the token gets stored in the Local Storage of the Browser or in the Cookies
On subsequent requests, for the user to be able to access any resources on the server side, they provide the token on each call usually in the Authorization Header
The server decodes the token to validate that this user is allowed to have access on this resource
Now, let’s have a closer look at the structure of JWT to understand the underlying details more. The token consists of 3 parts: a header, a payload and a signature separated by a dot: (Header.Payload.Signature). This is an example of a JWT token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.KTMtjpE5RsmxwEaDF_cDAelomv1QPTRu_t5sdGYZ2Bw
Header:
The header is a JSON object containing information about the signing algorithm and the type of the token. An example could look like this:
{
"alg": "HS256",
"typ": "JWT"
}
Then, spaces are removed from this JSON and the corresponding base64URL is calculated. For example, {"alg":"HS256","typ":"JWT"}
generates “eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9”
Payload:
The payload contains the information about the user to be used on the server side and this may include the user's email, id, name, etc. An important point to take care of is that anyone can access the information in the payload. So, secret information should never be included.
Example:
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
Then, base64URL is calculated for this payload after spaces are removed.
Signature:
Using a secret defined on the server side and an Encryption Algorithm, the combination of the encoded header and payload are then encrypted and added as a signature at the end of the token. This signature is used on the server side to validate that the message content is not tampered along the way by regenerating the signature again on the server side using the header and the payload sent and the secret stored on the server and compare them with the signature sent.
JWT example: analyzing ChatGPT login mechanism
In this section, I will go through a real life example by logging into ChatGPT and analyzing the token.
Knowing that most of the requests will require passing the Authorization Header, I sent a random message in a conversation and checked the network tab in the browser to get the details of the request.
Then, I got this token:
Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik1UaEVOVUpHTkVNMVFURTRNMEZCTWpkQ05UZzVNRFUxUlRVd1FVSkRNRU13UmtGRVFrRXpSZyJ9.eyJodHRwczovL2FwaS5vcGVuYWkuY29tL3Byb2ZpbGUiOnsiZW1haWwiOiJvbWFyZGlhYTUwMEBnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiZ2VvaXBfY291bnRyeSI6IkVHIn0sImh0dHBzOi8vYXBpLm9wZW5haS5jb20vYXV0aCI6eyJ1c2VyX2lkIjoidXNlci13bTBGd0Excll3STFpUnBDSmVSUkF1akkifSwiaXNzIjoiaHR0cHM6Ly9hdXRoMC5vcGVuYWkuY29tLyIsInN1YiI6ImF1dGgwfDYzYjQ4MzU5NmUxMWQxMmZlMzNlY2U3ZCIsImF1ZCI6WyJodHRwczovL2FwaS5vcGVuYWkuY29tL3YxIiwiaHR0cHM6Ly9vcGVuYWkub3BlbmFpLmF1dGgwYXBwLmNvbS91c2VyaW5mbyJdLCJpYXQiOjE2NzY0NjU2MjksImV4cCI6MTY3NzY3NTIyOSwiYXpwIjoiVGRKSWNiZTE2V29USGFzdzVueXl3aDVFNHlPbzZJdEciLCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG1vZGVsLnJlYWQgbW9kZWwucmVxdWVzdCBvcmdhbml6YXRpb24ucmVhZCBvZmZsaW5lX2FjY2VzcyJ9.qcDh1CtbpRyveAGJvbQ53SOdMIVweOzRtlc7w36qYLunEVOa7PK4_f_jykkr_d2d5VuSlf7VRvOkhfngHqHsmdwtOTz2PvngFmM4L1jOcgrZGFnEu65TKYZLg28txj_I53e3NDoKbW4TRatCMOHutC9yycTdMLv9bqgKN80YMZbwa4p_DdjxRcJ4g9vaY1zx-F2rPbXQes-eSiiHkyqzj74Qn2wfsYsMct01XHOubfoAcdAN-aTWWjMHdt8p8iXM0RnWMgM1e_d9RT5dMwJiS9H7xl7GMFNTL_SDqSeCjS7ohgp_YFucc3GhQj5RJtSCwZyg2FgniLhpkW7BCp5RPA
If we have a quick look at it, we can notice that the token has 3 parts separated by dots. So this is a good indication that it is a JWT token. Let’s analyze each part.
Header:
The first part is the header and it starts from the first character till the first dot:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik1UaEVOVUpHTkVNMVFURTRNMEZCTWpkQ05UZzVNRFUxUlRVd1FVSkRNRU13UmtGRVFrRXpSZyJ9
If we use any online base64URL decoder and enter the previous text, we will get the following JSON:
{
"alg":"RS256",
"typ":"JWT",
"kid":"MThENUJGNEM1QTE4M0FBMjdCNTg5MDU1RTUwQUJDMEMwRkFEQkEzRg"
}
From this, we are now sure that it is using JWT token as the “typ” field says JWT.
Payload:
The second part starts from the first dot to the second dot:
eyJodHRwczovL2FwaS5vcGVuYWkuY29tL3Byb2ZpbGUiOnsiZW1haWwiOiJvbWFyZGlhYTUwMEBnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiZ2VvaXBfY291bnRyeSI6IkVHIn0sImh0dHBzOi8vYXBpLm9wZW5haS5jb20vYXV0aCI6eyJ1c2VyX2lkIjoidXNlci13bTBGd0Excll3STFpUnBDSmVSUkF1akkifSwiaXNzIjoiaHR0cHM6Ly9hdXRoMC5vcGVuYWkuY29tLyIsInN1YiI6ImF1dGgwfDYzYjQ4MzU5NmUxMWQxMmZlMzNlY2U3ZCIsImF1ZCI6WyJodHRwczovL2FwaS5vcGVuYWkuY29tL3YxIiwiaHR0cHM6Ly9vcGVuYWkub3BlbmFpLmF1dGgwYXBwLmNvbS91c2VyaW5mbyJdLCJpYXQiOjE2NzY0NjU2MjksImV4cCI6MTY3NzY3NTIyOSwiYXpwIjoiVGRKSWNiZTE2V29USGFzdzVueXl3aDVFNHlPbzZJdEciLCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG1vZGVsLnJlYWQgbW9kZWwucmVxdWVzdCBvcmdhbml6YXRpb24ucmVhZCBvZmZsaW5lX2FjY2VzcyJ9
Now, if we decode the payload we get this:
{
"https://api.openai.com/profile":
{
"email": "omardiaa500@gmail.com",
"email_verified": true,
"geoip_country":"EG"
},
"https://api.openai.com/auth": {
"user_id":"user-wm0FwA1rYwI1iRpCJeRRAujI"
},
"iss":"https://auth0.openai.com/",
"sub":"auth0|63b483596e11d12fe33ece7d",
"aud": ["https://api.openai.com/v1","https://openai.openai.auth0app.com/userinfo"],
"iat":1676465629,
"exp":1677675229,
"azp":"TdJIcbe16WoTHasw5nyywh5E4yOo6ItG",
"scope":"openid profile email model.read model.request organization.read offline_access"
}
From this, we can see that ChatGPT includes some information about the user such as their email and their country and their id.
The signature cannot be checked because it is encrypted using a secret that is stored on ChatGPT servers.
Auth0 quick overview
Auth0 is an authentication and authorization platform that provides solutions for developers to authenticate and authorize users for their applications. Auth0 helps developers to implement secure user authentication and authorization in their applications, without having to worry about the underlying security and infrastructure. With Auth0, developers can use a variety of authentication methods, such as username and password, social login (such as Facebook, Google, or Twitter), single sign-on (SSO), and multi-factor authentication (MFA). Auth0 also provides API access management, which allows developers to manage and secure access to their APIs.
By using Auth0, developers can focus on building their application logic and user experience, without having to worry about the security and infrastructure required for user authentication and authorization. Auth0 is a popular tool used by many large and mid-sized companies. It is designed to be scalable and can accommodate a wide range of use cases, from small start-ups to large enterprises. Some of the well-known companies that use Auth0 include Microsoft, Twilio, Salesforce, and SAP. These companies use Auth0 to secure access to their applications and data, as well as to manage the authentication and authorization of their users.
Summary
Congratulations, you made it till the end of this article! In this article you learned the definition of Authentication and the difference between Authentication and Authorization. You learned the types of authentication: something you have, something you are and something you know. You also learned the normal authentication flow. Then, you learned about the difference between session-based and token-based tokens and went through a deep example of JWT token-based authentication. Finally, you learned about the useful tool Auth0 which provides authentication and authorization mechanisms for developers.