JSP can read HttpSession state, but session creation, authentication, fixation protection, timeouts, and invalidation belong in controllers, filters, and security infrastructure. Store only small identifiers or workflow state that truly must survive multiple requests.
A server session associates requests through a session identifier, usually carried by a cookie such as JSESSIONID. request.getSession() creates a session when none exists; request.getSession(false) returns null instead. Creating sessions for anonymous static views increases memory use and tracking unnecessarily.
A session expires after inactivity according to container or application configuration, or ends when invalidate() is called. A browser closing does not guarantee immediate server invalidation. Design explicit logout and timeout behavior and treat missing or expired state as a normal request outcome.
Session attributes are shared across requests from the same session and may be accessed concurrently from multiple browser tabs or parallel requests. Do not assume a mutable object is single-threaded. Prefer immutable values, small identifiers, or carefully synchronized updates.
Do not use the session as a general cache or store large result sets, uploaded files, credentials, database connections, request/response objects, or non-serializable infrastructure handles. In a distributed deployment, replication or an external session store adds size, serialization, consistency, and failure costs.
The session cookie should use Secure over HTTPS, HttpOnly to block ordinary script access, and an appropriate SameSite policy. Scope Path and Domain as narrowly as the application requires. Cookie flags reduce risk but do not replace CSRF defenses, authorization, or output encoding.
Never place secrets or trusted authorization claims directly in an unsigned client cookie. Treat client cookie values as untrusted input. If URL rewriting is enabled as a cookie fallback, session IDs can leak through links, logs, referrers, and screenshots; cookie-based sessions over HTTPS are safer for normal web applications.
After successful authentication, change the session identifier while preserving approved state. This prevents an attacker from choosing or learning a pre-login identifier and reusing it after the victim signs in. Invalidate the authenticated session on logout and clear the cookie according to the application framework.
Store the minimum identity reference needed to reload current authorization. Permissions can change while a session is active, so sensitive actions should use current server-side policy instead of trusting a stale role copied into the session indefinitely.
A JSP may read sessionScope to show user-specific navigation or a flash message, but it must not decide whether the underlying operation is allowed. A hidden administrative link is presentation behavior, not enforcement.
Pages that do not use sessions can disable automatic participation with the page directive. This avoids accidental session creation through implicit access and makes stateless pages easier to reason about.
HttpSession oldSession = request.getSession(false);
if (oldSession != null) {
oldSession.invalidate();
}
HttpSession session = request.getSession(true);
session.setAttribute("userId", authenticatedUser.id());
session.setMaxInactiveInterval(30 * 60);
response.sendRedirect(request.getContextPath() + "/account");
<%@ taglib prefix="c" uri="jakarta.tags.core" %>
<c:choose>
<c:when test="${empty sessionScope.userId}">
<a href="${pageContext.request.contextPath}/login">Sign in</a>
</c:when>
<c:otherwise>
<a href="${pageContext.request.contextPath}/account">Account</a>
</c:otherwise>
</c:choose>
getSession() creates a session if needed. getSession(false) returns the existing session or null, which avoids accidental creation.
Yes. Multiple tabs and parallel requests can access the same attributes concurrently, so mutable session objects need careful design.
No. The endpoint must authenticate and authorize every request independently of what the JSP displays.
Explore 500+ free tutorials across 20+ languages and frameworks.