从客户端与服务器建立HTTP连接到断开连接的过程,称为一个会话。一个会话可以包含多次请求与响应。
由于HTTP协议是无状态的,服务器无法区分前后两个请求是否来自同一设备,因此有了三种会话跟踪方案:Cookie
、Session
和JWT
。
Cookie
存储在浏览器中,发起请求时浏览器会自动带上Cookie,收到响应时浏览器会自动存储Cookie,是HTTP协议自带的功能。
Cookie的缺点:
- 只有浏览器支持Cookie,APP不支持
- 不安全,存在CSRF攻击,且用户可以禁用Cookie
- 不能跨域
代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @Slf4j @RestController public class CookieController {
@GetMapping("/cookie1") public Result cookie1(HttpServletResponse response) { response.addCookie(new Cookie("key", "value")); return Result.ok(); }
@GetMapping("/cookie2") public Result cookie2(HttpServletRequest request) { Cookie[] cookies = request.getCookies(); for (Cookie cookie : cookies) { if (cookie.getName().equals("key")) { log.debug(cookie.getValue()); } } return Result.ok(); } }
|
Session
Session是服务器在每个HTTP连接中对应的会话对象。Session存储在服务器中,其底层是基于Cookie实现的。
在建立连接第一次请求时,服务器会创建一个Session,每一次请求服务器都可以获取到其Session。每个Session有一个id,服务器响应数据时,会将Session的id放在Cookie中响应给浏览器。浏览器每次请求时会在Cookie中带上Session的id,服务器再根据id找到对应的Session,从而分辨前后两次请求是否是同一会话。
Session的优点:
- 存储在服务端,安全
缺点:
- 在服务器集群环境下无法直接使用,不同服务器Session不一致
- Cookie的缺点它也有
代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @Slf4j @RestController public class SessionController {
@GetMapping("/session1") public Result session1(HttpSession session) { session.setAttribute("key", "value"); return Result.ok(); }
@GetMapping("/session2") public Result session2(HttpServletRequest request) { HttpSession session = request.getSession(); log.info(session.getAttribute("key").toString()); return Result.ok(); } }
|
JWT
参观我的个人网站:http://saoke.fun