前面虽然讲解了session和token的区别,大致了解了session的用法以及具体实现的流程
但是在敲瑞吉外卖的时候还是有个问题
先看代码:
@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
@PostMapping("/login")
public R<Employee> login(HttpServletRequest request, @RequestBody Employee employee) {
//1.将页面提交的密码password进行md5加密
String password = employee.getPassword();
password = DigestUtils.md5DigestAsHex(password.getBytes());
//2.根据页面提交的用户名username查询数据库
LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Employee::getUsername, employee.getUsername());
Employee emp = employeeService.getOne(queryWrapper);
//3.如果没有查询到则返回登录失败结果
if (emp == null) {
return R.error("登录失败");
}
//4.密码比对,如果不一致则返回登录失败结果
if (!emp.getPassword().equals(password)) {
return R.error("登录失败");
}
//5.查看员工状态,如果为已禁用,则返回员工已禁用结果
if (emp.getStatus() == 0) {
return R.error("账号已禁用");
}
//6.登录成功,将员工id存入Session并返回登录成功结果
request.getSession().setAttribute("employee", emp.getId());
return R.success(emp);
}
/*
* 员工退出
* */
@PostMapping("/logout")
public R<String> logout(HttpServletRequest request) {
//清理session中保存的员工id
request.getSession().removeAttribute("employee");
return R.success("退出成功");
}
}
和之前的代码是一样的,但是这里有个问题,如果有多个用户登录,可以都保存为key值是employee吗?是不是这个代码就不管用了,是不是要改成多个值
答案:
-
正常来说不会冲突,因为Session 是和用户一一绑定的。
-
每个浏览器(或者说每个用户)在访问服务器时,都会有自己独立的一份
HttpSession。 -
同一个 Session 只对应一个用户的登录状态,所以在这个 Session 里面放一个
"employee"是没问题的。
简单理解就是:
-
A用户访问时,有自己的 Session,里面有自己的
employee。 -
B用户访问时,有另一个 Session,也有自己的
employee。 -
它们互不影响,不会覆盖或冲突。
🔵 Session是区分不同用户的,不是共享的!
什么时候会有问题?
-
如果是同一个 Session 里,想同时登录多个账号(比如开同一个浏览器不同标签页登录不同账号),
-
那你就需要考虑Session管理的问题了,比如用不同的 Key(比如
employeeA、employeeB)或者更复杂的机制。
但在绝大多数正常场景(每个用户自己登录自己账号)下, 👉 只用 "employee" 就够了,没问题。
那要不要改成保存多个值呢?
正常后台系统、商城系统:
-
不需要。
-
登录以后,一个 Session 对应一个用户,只保存一个
"employee"就好。
如果你要做那种支持"多账号切换"或者"同时保持多用户状态"的复杂应用,才需要保存多个。
所以总结:
| 情况 | 处理方式 |
|---|---|
| 普通系统(后台管理、APP、官网) | 一个 "employee",没问题 |
| 特殊系统(支持多用户同时在线,一个浏览器开多个账号) | 需要复杂管理,比如 Map |
但是服务器和浏览器之间不是一对多的关系吗,既然session是存在服务器里的,每次用户登录进来都需要判断session是否存在并比对id是否相等,那么有多个浏览器登录,服务器就只存储一个session不会有问题吗
服务器和浏览器之间是一对多没错!
✅ 一个服务器上可以有很多个浏览器(很多个客户端用户)访问。
✅ 但是每一个浏览器(或者说客户端)和服务器之间,其实是用Session ID来绑定自己的独立Session的!
重点来了:
服务器上是存了很多个 Session 的,每个用户(浏览器)都有自己的 Session,不是所有人共用一个!
具体工作流程(非常重要)
也就是说:
服务器是根据 Session ID,把每个用户隔离开来的!每个浏览器的 Session 是独立的、互不影响的。每个 Session 都可以保存自己的 "employee"。
所以张三登录,服务器给张三一份 Session,张三的 Session 里有自己的 employee。
他们虽然都叫 "employee",但存储在不同 Session 里,所以不会冲突。
服务器上 Session 是什么样的?
你可以想象成服务器上有一个大的 Session 管理器,里面是这样的:
李四登录,服务器给李四另一份 Session,李四的 Session 里有李四的 employee。
-
浏览器第一次访问服务器的时候,服务器给它生成一个全新的 Session,比如:JSESSIONID=abc123
-
服务器把这个 JSESSIONID 通过
Set-Cookie返回给浏览器。-
浏览器收到以后,把这个 Cookie 存起来。
-
-
以后这个浏览器再访问服务器时,就会自动带上这个 Cookie(JSESSIONID)。
-
服务器根据你带过来的
JSESSIONID=abc123,去找到属于你的 Session。
-
-
每个浏览器都有自己独立的 Cookie(JSESSIONID),所以服务器知道:
-
A浏览器(Session1)
-
B浏览器(Session2)
-
C浏览器(Session3)
-
| Session ID | 保存的数据 |
|---|---|
| abc123(张三的浏览器) | employee=张三 |
| def456(李四的浏览器) | employee=李四 |
| ghi789(王五的浏览器) | employee=王五 |
Session 是一份一份单独存在的,key是Session ID。
| 问题 | 答案 |
|---|---|
| 多个浏览器登录,Session 会冲突吗? | 不会!每个浏览器有自己的 Session(通过 JSESSIONID 识别) |
| 服务器上只有一个 Session 吗? | 不是!服务器维护了很多 Session,一个用户一个 Session |
| 登录后要每次比对 id 吗? | 正常不需要!只要拿当前 Session 里的 employee 就可以了 |
| employee key 会冲突吗? | 不会!每个 Session 各管各的 |

第一次登录时,浏览器发送登录请求。
服务器创建一个 Session 对象,把 employee=张三 保存进去。
后续每次请求,浏览器都会自动带上 JSESSIONID,服务器根据这个找到对应的 Session,从中拿到员工信息。
因为每个浏览器有独立的 Session,所以多个用户互不影响!
2075

被折叠的 条评论
为什么被折叠?



