Introduction
Identity authentication plays a crucial role in protecting data access and user privacy in internet applications, especially for enterprises' internal applications. In this series of articles, we will explore identity authentication from different perspectives, with a specific focus on identity authentication practices in application engineering in this one.
In various applications, identity authentication commonly employs the following two techniques:
Cookie & Session: This traditional authentication mechanism is widely used in web applications, primarily within browsers. It verifies user identity and maintains the session state using cookies and sessions.
Bearer Token: This is a more modern authentication mechanism that eliminates the reliance on browser cookies and instead utilizes the HTTP protocol for authentication. It is particularly suitable for API scenarios and can be used in mobile applications.
Regardless of the chosen method, developers need to select the appropriate authentication approach for their products to ensure data security, user privacy, and a seamless user experience.
Traditional Web Applications
In the past, we used Java JSP to directly build web applications, identifying users using JSESSIONID, a session ID stored in a cookie on the client's browser and carried with each request.
However, this approach had certain issues. Since cookies are managed and stored on the client device by the browser, malicious attackers could steal the stored session ID and impersonate the user, posing a security risk. Additionally, developers sometimes struggled to set reasonable expiration periods and security requirements for cookies and sessions.
When developing these applications, developers often had to implement authentication separately for each system, which was independent and used different identity systems. This necessitated repetitive work. In such cases, Single Sign-On (SSO) could address these challenges by utilizing a unified authentication system, requiring minimal integration work in each individual web application to achieve authentication functionality.
In recent years, both front-end and back-end technologies have made rapid progress. Developers have begun to migrate to more modern tech stacks, leaving applications powered by outdated technologies as legacy platforms. However, there are instances where new identity security requirements arise, but modifying the old code is not feasible. In such cases, an alternative approach is to use middleware working as a reverse proxy to perform authentication. Before the client reaches the application, the middleware redirects the user to an external authentication interface, where the user logs in. The middleware then obtains the user's identity information and attaches it to the request before passing it to the old application. This enables developers to add new authentication mechanisms to old applications without modifying the existing code.
Web Application Evolution: Front-End Separation from Back-End
With the emergence of new front-end technologies such as Vue and React, web interactions have been revolutionized. In the past, users had to fill and submit forms on web pages, interacting with the back-end using HTML forms and buttons, which did not provide a smooth user experience. Now, interactions on the page are real-time, and developers use JavaScript scripts to interact with back-end APIs, offering a more consistent and continuous experience. User interactions have shifted from direct HTTP requests to invoking various APIs.
There are some differences in identity authentication mechanisms between web page-oriented applications and API-oriented applications. While old cookies can still be used, they are not suitable for modern front-end technologies. New technologies empower developers with more expressive code, allowing them to perform more operations, including scenarios where we may need to switch user accounts on the front end. However, implementing this directly in the front end through cookies is challenging (for security reasons, cookies related to user identity are often configured as httpOnly, preventing JavaScript scripts from reading and manipulating them).
Typically, modern front-end applications manage user sessions themselves. Once a user successfully logs in, the front end manages the token generated by the backend and adds it to the request header when making API calls for the backend to identify the user's identity. APIs use tokens to identify user information. There are various technical means available, such as manually implementing token mechanisms using JSON Web Tokens (JWT). The JWT payload stores identification information such as the user ID, which is then signed to allow the backend to verify the token and retrieve user identity information.
However, JWT also has some drawbacks, such as:
The expiration time of JWT is fixed and cannot be modified once the signature is completed. Since it is typically not stored by the backend and only undergoes signature verification, it is not possible to revoke the token, which poses a risk of token theft.
Payload data is stored in plaintext and can be parsed by the client, making it unsuitable for storing confidential information.
Fortunately, there are now new JWT specifications to address these shortcomings. The JWT payload can include a field called "jti" to store a unique identifier for the JWT, which can be stored in the backend cache to control the JWT's lifecycle. Additionally, the JSON Web Encryption (JWE) specification defines an encrypted JWT extension that combines the advantages of asymmetric and symmetric encryption, ensuring that the payload is transmitted in ciphertext form to prevent leakage.
Furthermore, there are other JWT-based technologies that provide more mature solutions, such as OpenID Connect. It's important to note that OpenID Connect does not depend on JWT, but they can be used together. OpenID Connect standardizes the mechanisms for access tokens and refresh tokens, allowing developers to use short-term tokens to mitigate the risk of token theft. The ecosystem of OpenID Connect is also thriving, with many server and client implementations available to help developers build identity authentication systems based on the OpenID Connect protocol. Additionally, open-source identity authentication solutions like Keycloak can assist developers in implementing secure identity authentication services.
New front-end technology practices, such as Next.js, are gradually introducing server-side rendering techniques to the front-end domain. This represents a fresh evolution of the old web development paradigm, combining React with back-end programs to further enhance user experience. There are now more libraries, such as NextAuth, that can help developers implement identity authentication using this mechanism, making the authentication process more developer-friendly.
API Gateways and Identity Authentication
Let's consider how our mobile applications interact with data. Do they also use APIs? In mobile applications, there is no cookie mechanism like in browsers to store user sessions, so they primarily use tokens to pass information through HTTP request headers.
What about API services? A successful application backend typically consists of many complex API systems that require a unified identity authentication mechanism. Otherwise, developers would have to implement the same authentication mechanism for each service, which would be cumbersome.
API gateways can help us solve this problem by handling authentication and parsing tasks similar to cookies or tokens, and directly passing the parsed identity information to the backend services, reducing duplication of work. Apache APISIX and API7 Enterprise also support out-of-the-box OpenID Connect authentication functionality, helping users integrate identity authentication services directly. Additionally, API gateways support the implementation of any authentication mechanism through scripting, so even with custom identity authentication mechanisms, they can be integrated on the API gateway, simplifying application development.
Summary
The development of user interaction methods has driven advancements in identity authentication. The API-centric approach is becoming a mainstream trend, and APIs may be provided by microservice architectures, necessitating a unified identity authentication mechanism to reduce redundant development. Therefore, we should choose more modern mechanisms such as OpenID Connect and JWT, and using an API gateway can provide additional functionality for API development.