Understanding the Workflow of Cookies and Sessions in Web Development
Basic Concepts of Cookies and Sessions
Introduction: The HTTP protocol is a stateless protocol.
A stateless protocol means that HTTP does not retain the state information from previous interactions during transmission. However, in certain scenarios, state information must be preserved. For instance, when shopping on an e-commerce platform, you need to maintain your logged-in state while browsing products. The Cookie mechanism is an excellent solution to address this.
A Cookie is an attribute in the
headerof an HTTP request, structured as a key-value pair, used to store identity information.
Cookies provide a mechanism for browsers to persistently store data. After you log in (upon receiving the response from the server), the relevant user information is saved in the browser's Cookies. When you navigate to other pages, the data in the Cookies is sent to the server along with the request message. Once the server receives the request, it identifies which user is browsing.
User information contains various data, such as passwords, account balances, and user preferences. On the server side, this data is organized using an in-memory structure called a Session. Within a Session, data is stored as key-value pairs (typically within a Map structure). This collection of stored user information is managed on the server using the HttpSession class. This means that every session has a corresponding HttpSession object.
In reality, what is specifically stored in the Cookie is the identity identifier (session ID). The server's Session stores the user inofrmation corresponding to that session ID. The session ID acts like an ID card number; the client sends a Cookie containing this ID to the server, and the server uses it to retrieve the corresponding identity information.
- Mechanism for client-side data storage: Cookies
- Mechanism for server-side data storage: Sessions
These two mechanisms often work in tandem.
Furthermore, every user has a unique session ID and a corresponding server-side Session that stores their identity information (just as every person has a unique ID card number).
Core Methods
1. Methods in the HttpServletRequest Class
The getSession Method
Creates a session.
If this is not the user's first login, this method will first look up the corresponding HttpSession object in the map based on the session ID found in the request's Cookie, thereby retrieving the user information.
If this is the first login, the session has not yet been created, meaning no session ID exists. This method will automatically generate a new session ID and store it along with the newly created HttpSession object in the map. Simultaneously, it will automatically insert the session ID into the response header under the Set-Cookie field. Upon receiving this, the browser saves the session ID in its Cookies.
2. Methods in the HttpServletResponse Class
3. Methods in the HttpSession Class
Each session corresponds to an HttpSession object. Through this class, we can define custom user information (as key-value pairs) within the session and retrieve the corresponding value based on the key.
Summary: Each Session is organized as a key-value pair (session ID -> Session). The content within a Session is also organized as key-value pairs (key -> value).
Mini Project: Simulating User Login
The most common use case for the Cookie/Session mechanism is user authentication.
A login request is sent from the frontend, which can be accomplished using various methods (AJAX or form submission). Although AJAX offers more functionalities, standard form submissions are often preferred for login scenarios due to their simplicity.
Interaction Logic:
- The client enters a username and password on the frontend interface and clicks "Login", sending an HTTP POST request.
- The server receives the request, parses the data based on the body format, and extracts the username and password.
- The server validates the credentials. If they are incorrect, the login is denied. If correct, the server creates a Session and sets relevant attributes.
- Upon successful login, the appliaction should redirect to a main homepage, so the server sends a redirect response.
- The client receives the response and renders the interface.
Frontend Code
html
Authentication Servlet Code
java @WebServlet("/authenticate") public class AuthenticationServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 1. Receive the request and parse the body data // Ensure the encoding matches to prevent character corruption req.setCharacterEncoding("UTF-8"); String account = req.getParameter("userAccount"); String secret = req.getParameter("userSecret");
// 2. Validate the credentials
// Hardcoded for demonstration: account="admin", secret="password123"
if (!"admin".equals(account) || !"password123".equals(secret)) {
resp.setContentType("text/html; charset=utf-8");
resp.getWriter().write("Invalid credentials, please try again!");
return;
}
// 3. Credentials are correct
// Create a session
// If a session already exists, it retrieves it; otherwise, it creates a new one (true flag)
HttpSession currentSession = req.getSession(true);
currentSession.setAttribute("currentUser", account);
Instant authTime = Instant.now();
currentSession.setAttribute("authTimestamp", authTime);
// 4. Send a redirect response to the main page
resp.sendRedirect("dashboard"); // No leading slash required here
}
}
Dashboard Servlet Code
java @WebServlet("/dashboard") public class DashboardServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // Display the main dashboard
// Retrieve the current user's session information
// Passing false means it will not create a new session if one doesn't exist
HttpSession currentSession = req.getSession(false);
if (currentSession == null) {
resp.setContentType("text/html; charset=utf-8");
resp.getWriter().write("You are not currently authenticated!");
return;
}
// Retrieve attributes (requires casting from Object)
String account = (String) currentSession.getAttribute("currentUser");
Instant authTime = (Instant) currentSession.getAttribute("authTimestamp");
resp.setContentType("text/html; charset=utf-8");
String responseBody = "Welcome, User: " + account + "<br>Last Authenticated At: " + authTime;
resp.getWriter().write(responseBody);
}
}
Demonstration:
This concludes the overview of the workflow of Cookies and Sessions in web development.