一、会话技术
会话:
用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中可以包含多次请求和响应。
会话跟踪:
一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便在同一次会话的多次请求间共享数据。
会话跟踪方案:
- 客户端会话跟踪技术:Cookie
- 服务端会话跟踪技术:Session
- 令牌技术
二、Cookie
设置Cookie
public Result cookie1(HttpServletResponse response) {
response.addCookie(new Cookie("login_username","ming")); // 设置Cookie
return Result.success();
}
获取Cookie
public Result cookie2(HttpServletRequest request) {
Cookie[] cookies = request.getCookies(); // 获取所有的Cookie
for (Cookie cookie : cookies) {
if ("login_username".equals(cookie.getName())) {
System.out.println("login_username:" + cookie.getValue());
}
}
return Result.success();
}
常用方法
方法 | 说明 |
---|---|
new Cookie(key, value) | 新建Cookie |
request.getCookies() | 获取所有的Cookie |
response.addCookie(cookie) | 响应Cookie |
cookie.getName() | 获取Cookie的Key |
cookie.getValue() | 获取Cookie的Value |
优缺点
优点:HTTP协议中支持的技术
缺点:
- 移动端APP无法使用Cookie
- 不安全,用户可以自己禁用Cookie
- Cookie不能跨域
三、Session
设置Session
public Result session1(HttpSession session) {
log.info("HttpSession-s1:{}", session.hashCode());
session.setAttribute("loginUser", "ming"); // 设置Session
return Result.success();
}
获取Session
public Result session2(HttpServletRequest request) {
HttpSession session = request.getSession();
log.info("HttpSession-s2:{}", session.hashCode());
Object loginUsername = session.getAttribute("loginUser"); // 从Session中获取数据
log.info("loginUsername:{}", loginUsername);
return Result.success(loginUsername);
}
常用方法
方法 | 说明 |
---|---|
request.getSession() | 获取session |
session.hashCode() | 获取session的hash值 |
session.getAttribute(key) | 根据Key获取Value |
session.setAttribute(key, value) | 设置session |
优缺点
优点:存储在服务器,安全
缺点:
- 服务器集群环境下无法使用session
- Cookie的缺点
四、JWT令牌技术【推荐使用】
定义了一种简洁的,自包含的格式,用于在通信双方以json数据格式安全的传输信息。由于数字签名的存在,这些信息是可靠的。
优点:
- 支持PC端,移动端
- 解决集群环境下的认证问题
- 减轻服务器端存储压力
缺点
:需要自己实现
4.1 生成JWT令牌
POM依赖
<!-- JWT 令牌 -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
报错:javax/xml/bind/DatatypeConverter
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
public void testGenJWT() {
Map<String, Object> claims = new HashMap<>();
claims.put("id", 1);
claims.put("name", "tom");
String jwt = Jwts.builder()
.signWith(SignatureAlgorithm.HS256, "ming") // 签名算法
.setClaims(claims) // 自定义内容
.setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000)) // 设置有效期为1h, 这里的单位是毫秒
.compact();
System.out.println(jwt);
}
4.2 解析JWT令牌
public void testParseJWT() {
Claims claims = Jwts.parser()
.setSigningKey("ming") // 密钥
.parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoidG9tIiwiaWQiOjEsImV4cCI6MTcwNDUyMjY4N30.epp-MFAf1GvpdMxrVXrlOf7vDQKyXcujms71PzJML8k") // JWT令牌
.getBody();
System.out.println(claims);
}