目录
会话技术
会话跟踪方案对比
方案一:Cookie
实现思路
具体代码
优点
缺点
方案二:Session
实现思路
具体代码
优点
缺点
方案三:令牌技术(主流方案)
实现思路
优点
缺点
会话技术
- 会话:用户打开浏览器,访问web服务的资源,会话建立,直到一方断开连接,会话结束。在一次会话中包含多次请求和响应。
- 会话跟踪:一种维护浏览器状态的方法,浏览器需要识别多次请求是否来源于同一个浏览器,以便在同一次会话的多次请求之间共享数据。
- 会话跟踪方案
- 客户端会话跟踪技术:Cookie
- 服务端会话跟踪技术:Session
- 令牌技术
会话跟踪方案对比
-
方案一:Cookie
-
实现思路
- 在浏览器第一次发送请求,请求服务器时,可以设置一个Cookie,在Cookie可以存储相关的信息,然后服务器端将Cookie自动(Set-Cookie:name=valie,用于设置Cookie的数据)响应给浏览器,浏览器接收到Cookie后,会自动将Cookie的值(name=value)存储到浏览器本地,以后的请求都会自动将存储在本地的Cookie中的数据(Cookie:name=value,用于携带Cookie的数据)传送到服务端,在服务端就可以获取到该Cookie的值,并且判断该Cookie中的值是否存在。
-
具体代码
-
package com.example.tlias.controller; import com.example.tlias.pojo.Result; import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController @Slf4j public class SessionController { @GetMapping("/c1") // todo 设置Cookie public Result cookie1(HttpServletResponse response) { response.addCookie(new Cookie("login_name", "hkm")); return Result.success(); } @GetMapping("/c2") // todo 获取Cookie public Result cookie2(HttpServletRequest request) { Cookie[] cookies = request.getCookies(); for (Cookie cookie : cookies) { if (cookie.getName().equals("login_name")) { System.out.println("login_name:" + cookie.getValue()); } } return Result.success(); } }
-
访问c1运行结果如下
-
访问c2运行结果如下
-
优点
- Http协议中支持的技术
-
缺点
- 移动端APP无法使用Cookie
- 不安全,用户可以自己禁用Cookie
- Cookie不能跨域(跨域区分的三个维度:协议、ip/域名、端口)
-
-
方案二:Session
-
实现思路
- Sesnsion是服务器端会话跟踪技术,Session是存储在服务器端的,其底层是基于Cookie实现的,在浏览器发送请求请求服务器时,服务器端会自动创建Session会话对象,每一个Session会话对象都会有一个ID,我们称之为SessionID,服务器响应浏览器时会将Session对象的ID通过Cookie响应给浏览器(Set-Cookie:JSESSIONID=1),浏览器会自动存储接受到的Cookie对象至本地,然后在后续的请求会将Cookie的值携带到服务端,服务器获取到Cookie的值(即Session的id),就会找到当前请求的会话对象Session。
-
具体代码
-
package com.example.tlias.controller; import com.example.tlias.pojo.Result; import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpSession; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController @Slf4j public class SessionController { // todo 在HttpSession中设置session对象的值 @GetMapping("/s1") public Result Session1(HttpSession session) { log.info("HttpSession:{}", session.hashCode()); session.setAttribute("loginUser-s1","hkm");// 往Session对象中存储 return Result.success(); } @GetMapping("/s2") // todo 获取=session对象的值 public Result Session2(HttpServletRequest request) { HttpSession httpSession = request.getSession(); log.info("HttpSession-s2:{}", httpSession.hashCode()); Object loginUser = httpSession.getAttribute("loginUser"); log.info("loginUser:{}", loginUser); return Result.success(loginUser); } }
- 访问s1运行结果如下:
-
访问s2运行结果如下
-
-
优点
- 数据存储在服务端,安全
-
缺点
- 服务器集群环境下无法直接使用Sesson
- Cookie的缺点(Session的底层是基于Cookie实现的)
-
-
方案三:令牌技术(主流方案)
-
实现思路
- 令牌是用户身份的标识,本质是一个字符串,浏览器发起请求,在请求登录接口时,如果登陆成功,服务端可以生成一个令牌,该令牌是该用户的合法身份凭证,接下来响应数据的时候就可以直接将令牌响应给前端,前端就会将令牌存储起来(可以存储在Cookie中也可以存储在其他存储空间中),接下来的每一次请求都会将令牌携带到服务端,服务端会校验该令牌的有效性。
-
优点
- 支持PC端、移动端
- 解决集群环境下的认证问题
- 减轻服务器的存储压力
-
缺点
- 需要自己实现
-