Modern web apps favor frontend–backend separation: frontend focuses on UX, backend on data/logic. This benefits development and maintenance, but it also raises questions about user authentication.
After several projects’ architecture design and development, I have a more systematic understanding of this area. I’m summarizing it here; welcome to criticize and correct me.
How to authenticate users?
Traditional: session + cookie

HTTP is stateless, but with the enrichment of requirements, we need to know the user’s state to provide different services, which led to the existence of cookies and sessions.
What is a cookie?
Cookies are a solution for maintaining state on the client side. By definition, a cookie is special information sent by the server to the client, stored as a text file on the client, and then the client brings this special information with every subsequent request to the server.
What is a session?
Sessions maintain state through the server. Since the term “Session” has many semantic meanings, it’s necessary to clarify its meaning here. First, we usually translate Session as “会话” (huìhuà), so we can refer to a series of interactions between the client browser and the server as a Session. From this semantic perspective, we talk about the duration of a Session and what operations were performed during the Session; second, Session refers to the storage space opened by the server for the client, and the information stored in it is used to maintain state. From this semantic perspective, we refer to what content is stored in the Session and how to retrieve matching content from the Session based on key values.
Using session + cookie
When a user logs in, the server creates a session, generates a sessionId, and writes it to the frontend Cookie. In each subsequent request, the sessionId is included, and the server retrieves the corresponding user’s identity information through the sessionId.
Of course, if we are actually developing using the Spring framework, creating a session and writing it to the response Cookie will be automatic.
A step forward: JWT

Compared to the previous session and cookie mechanism, the token mechanism is an improvement. For user authentication, the server-side session is actually unnecessary and no storage is required. When a user logs in successfully, the backend issues a token. The user information for identity verification can be directly encrypted and encapsulated in the token. The server returns the token to the frontend, which stores it in a Cookie, while the server doesn’t need any storage. In subsequent requests, the user carries the token in the request header. The server will decrypt the token to check if it has expired or if it is present.
Why is this an improvement?
- The client need not be a browser
When we use the traditional session + cookie scheme, we actually need to write the session into a cookie, which determines that our frontend must be a browser. In today’s popular APP era, this is too limited. For example, an APP actually uses SQLite as its storage medium.
- Auth can be an independent service
The traditional scheme actually binds user authentication and API services together, while JWT is just a simple token that also carries key user information, so an independent service can be created specifically for issuing tokens. When we are doing SSO or third-party API integration, we will notice that many authorization services are independent. This is decoupling, this is progress, and this is the charm of this scheme.

