什么是 Session?Web 开发中 Session 的使用与注意事项

什么是 Session?Web 开发中 Session 的使用与注意事项

✅ 引言

在 Web 开发中,HTTP 协议是无状态的,这意味着每次请求之间没有关联。为了实现用户登录、购物车、权限控制等功能,服务器需要一种机制来“记住”用户。Session(会话) 就是解决这一问题的核心技术之一。

本文将深入讲解:

  • 什么是 Session?
  • Session 的工作原理
  • 在 Java Web 和 Spring Boot 中如何使用 Session
  • 使用 Session 的最佳实践与常见注意事项
  • 安全风险与应对策略

并提供完整的 Java + Spring Boot 示例代码,帮助你全面掌握 Session 的使用。


📌 一、什么是 Session?

1.1 基本定义

Session(会话)是服务器端用于保存用户状态的一种机制。当用户访问服务器时,服务器为其创建一个唯一的会话(Session),并在内存或存储中保存该用户的相关信息(如登录状态、用户ID等)。

每个 Session 都有一个唯一的 Session ID,通常通过 Cookie 发送给客户端,后续请求中客户端携带该 ID,服务器据此识别用户。想象 Session 就像超市给你的会员卡,第一次访问时服务器给你生成一张唯一的 “会员卡”(Session ID),以后每次访问你都出示这张卡,服务器就能通过卡片识别你的身份和之前的操作记录。

1.2 工作流程图解

在这里插入图片描述

1.3 Session 的工作原理

Session的工作流程可以分为四个阶段:

  1. 创建阶段:当用户第一次访问服务器时,服务器会生成一个唯一的Session ID,并创建对应的Session对象存储用户数据。
  2. 传输阶段:服务器通过Set-Cookie响应头,将Session ID发送给客户端,客户端会将其保存在Cookie中。
  3. 验证阶段:后续请求中,客户端会自动在Cookie中携带Session ID,服务器通过这个ID找到对应的Session对象。
  4. 销毁阶段:当用户登出或会话超时后,服务器会删除Session对象,客户端Cookie也会被清除或标记为过期。

📌 二、Session 的使用场景

  • 用户登录状态保持
  • 购物车信息存储
  • 表单防重复提交
  • 一次性验证码(如短信验证码)
  • 权限控制与访问记录

📌 三、Java Web 中使用 Session(原生 Servlet)

3.1 获取或创建 Session

@WebServlet("/login")publicclassLoginServletextendsHttpServlet{@OverrideprotectedvoiddoPost(HttpServletRequest req,HttpServletResponse resp){String username = req.getParameter("username");// 获取或创建 SessionHttpSession session = req.getSession();// 存储用户信息 session.setAttribute("username", username); session.setAttribute("loginTime",newDate()); resp.getWriter().println("登录成功,欢迎 "+ username);}}

3.2 读取 Session 数据

@WebServlet("/profile")publicclassProfileServletextendsHttpServlet{@OverrideprotectedvoiddoGet(HttpServletRequest req,HttpServletResponse resp){HttpSession session = req.getSession(false);// 不自动创建if(session !=null&& session.getAttribute("username")!=null){String username =(String) session.getAttribute("username");Date loginTime =(Date) session.getAttribute("loginTime"); resp.getWriter().println("用户:"+ username +",登录时间:"+ loginTime);}else{ resp.setStatus(401); resp.getWriter().println("请先登录");}}}

3.3 注销 Session

@WebServlet("/logout")publicclassLogoutServletextendsHttpServlet{@OverrideprotectedvoiddoGet(HttpServletRequest req,HttpServletResponse resp){HttpSession session = req.getSession(false);if(session !=null){ session.invalidate();// 销毁 Session} resp.getWriter().println("已退出登录");}}

📌 四、Spring Boot 中使用 Session

4.1 启用 Session 支持(默认已开启)

@RestControllerpublicclassUserController{@PostMapping("/login")publicStringlogin(@RequestParamString username,HttpServletRequest request){HttpSession session = request.getSession(); session.setAttribute("username", username);return"登录成功,用户:"+ username;}@GetMapping("/info")publicStringgetUserInfo(HttpServletRequest request){HttpSession session = request.getSession(false);if(session !=null&& session.getAttribute("username")!=null){return"当前用户:"+ session.getAttribute("username");}return"未登录";}@GetMapping("/logout")publicStringlogout(HttpServletRequest request){HttpSession session = request.getSession(false);if(session !=null){ session.invalidate();}return"已退出";}}

4.2 使用 @SessionAttribute 注解(更优雅)

@Controller@SessionAttributes("user")publicclassSessionController{@PostMapping("/login")publicStringlogin(@RequestParamString username,Model model){ model.addAttribute("user",newUser(username));return"redirect:/dashboard";}@GetMapping("/dashboard")publicStringdashboard(@SessionAttribute("user")User user,Model model){ model.addAttribute("user", user);return"dashboard";}}

📌 五、Session 的注意事项与最佳实践

5.1 安全性问题

风险解决方案
Session 劫持使用 HTTPS、设置 SecureHttpOnly Cookie
Session 固定攻击登录成功后调用 session.invalidate() 并创建新 Session
Session 泄露敏感信息不要存入 Session(如密码)
// 在 Spring Boot 中配置 server.servlet.session.cookie.http-only=true server.servlet.session.cookie.secure=true server.servlet.session.cookie.same-site=strict 

5.2 性能与可扩展性

  • 内存占用:Session 默认存储在服务器内存中,大量用户会消耗内存。
  • 集群部署问题:多台服务器时,Session 无法共享。
解决方案:
  • 使用 Redis 存储 Session(推荐)
  • 使用 Spring Session + Redis
<!-- pom.xml --><dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-data-redis</artifactId></dependency>
# application.ymlspring:session:store-type: redis redis:host: localhost port:6379

5.3 Session 过期时间

# application.ymlserver:servlet:session:timeout: 30m # 30分钟

或在代码中设置:

session.setMaxInactiveInterval(1800);// 秒

✅ 总结

项目说明
Session 本质服务器端状态保持机制
核心原理通过 Session ID 识别用户
优点简单易用、数据安全(不暴露给客户端)
缺点占用服务器资源、集群部署需共享
最佳实践使用 Redis 存储、设置合理过期时间、防止 Session 劫持
替代方案JWT(无状态认证)

📚 推荐

Read more

WebGIS视角:体感温度实证,哪座“火炉”火力全开?

WebGIS视角:体感温度实证,哪座“火炉”火力全开?

目录 前言 一、火炉城市空间分布及特点 1、空间分布 2、气候特点 二、数据来源及技术实现 1、数据来源介绍 2、技术路线简介 三、WebGIS系统实现 1、后端设计与实现 2、前端程序实现 四、成果展示 1、整体展示 2、蒸烤模式城市 3、舒适城市 五、总结 前言         “火炉城市”是中国对夏季天气酷热的城市的夸张称呼。这一说法最早出现在民国时期,当时媒体有“三大火炉”之说,即重庆、武汉和南京,都是长江沿线的著名大城市,分别居于长江的上、中、下游,因夏季气温炎热,被媒体夸张地称为“火炉”。新中国成立后,又有了“四大火炉”之说,

By Ne0inhk
vue-router(vue 路由)基本使用指南(二)

vue-router(vue 路由)基本使用指南(二)

文章目录 * 深入使用 * 导航守卫 * 重定向与别名 * history 配置:指定历史模式 * 路由元信息(meta) * 拓展 * 状态管理(Pinia / Vuex) * Pinia / Vuex 介绍 * Vuex vs Pinia * Pinia 基本使用 * Pinia 使用 Cookies 存储 深入使用 导航守卫 导航守卫用于在路由跳转前、跳转后或解析过程中,添加自定义的逻辑处理,例如权限验证。 * to 和 from 是即将进入的目标路由和当前导航正要离开的路由 * next 是一个函数,该函数用于控制路由的跳转。 * next():继续执行路由。 * next(false):中断当前路由,如果浏览器的 URL 改变了,那么 URL 会回到 from

By Ne0inhk
前端HTML、CSS、JS、VUE 汇总

前端HTML、CSS、JS、VUE 汇总

前言 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 使用VS Code运行前端代码 在VS Code上安装前端插件 正在更新中~ ✨ 文章目录 * 前言 * HTML+CSS * JS * Vue2 * Vue3 提示:这里可以添加本文要记录的大概内容: HTML+CSS 学习 https://developer.mozilla.org/zh-CN/docs/Learn/CSS 学习路线知识定位HTML基础标签、表格、表单、按钮、div、单元格合并CSS基础基本语法、选择器、使用方式、优先级、层叠样式、继承特性CSS常用样式字体样式、文本样式、列表样式、背景样式、鼠标样式、伪类样式、设置透明度CSS 内容盒子与边框盒子边框、内边距与外边距CSS+HTML实现元素定位相对定位、绝对定位、

By Ne0inhk
从传统Web到API驱动:使用Django REST Framework重构智能合同审查系统

从传统Web到API驱动:使用Django REST Framework重构智能合同审查系统

目录 1. 我们面临的三个核心问题 2. 场景实战:合同列表展示 2.1 传统 Django 模版系统实现 2.2 解耦后的 Django + DRF + 前端分离实现 3. 进阶技术实践 3.1 认证升级:集成 JWT 与自定义响应 3.2 复杂业务逻辑处理:APIView 的灵活性 4. 遇到的挑战与解决方案 挑战一:跨域资源共享 (CORS) 挑战二:文件上传与静态资源管理 5. 总结 在智能合同审查系统的开发演进过程中,我们经历了一次重要的架构转型:从传统的 Django 模版系统(MVT)迁移到了前后端分离的 API 驱动架构(Django REST

By Ne0inhk