1. cookie
- 以 k1=v1;k2=v2… 形式在浏览器保存的少量(同一网站最多存20个)文本数据
- 保存了的cookie在以后的每次请求中都会携带
- cookie默认不支持中文
- cookie存放原始数据在本地不安全
从服务器发送cookie给浏览器保存
Cookie cookie = new Cookie("username", "zhangsan");
response.addCookie(cookie);
cookie的生命周期
cookie随浏览器的进程关闭而销毁,所以浏览器一般会把cookie自动保存在本地
setMaxAge(int expiry)可以设置cookie存活时间,单位为秒
- 正数:按秒计算存活的时间
- 负数:随浏览器关闭而销毁,默认设置的-1
- 0:直接销毁,销毁方式是重写一个同名cookie并设置其 setMaxAge(0)
获取cookie
Cookie[] cookies = request.getCookies();
if(cookies != null){
for(Cookie c : cookies){
String key = c.getName();
String value = c.getValue();
if(key.equals("username")){
System.out.println(value);
}
}
}
2. session(会话)
- session是在服务器端保存的大量map数据
- tomcat 生成的 sessionID 叫做 JESSIONID,为每个map都设置,作为其唯一标识
- 浏览器cookie只保存 JESSIONID,每次请求时都会携带,原始数据在服务器端,安全
缺点
- 当同时请求的用户很多,会增加服务器负载
- sessionID在cookie中,如果cookie在传递过程中被截获并篡改,可用来攻击服务器
- sessionID仅是一个普通的特征值,携带的信息太少,不易扩展
创建session,获取jessionID
HttpServletRequest.getSession(); //第一次调用会自动创建jessionID
session.setAttribute("username","zhangsan"); //手动创建session
session.getAttribute("username"); //获取session属性值
当浏览器第一次访问服务器 ,服务器中还没有保存对应的 session,需要手动在servlet请求(即在handler方法中)先创建session,然后session会以 cookie 的形式response给浏览器一个JESSIONID,以后浏览器再次访问服务器,都会自动携带这个JESSIONID,就可以直接取出服务器保存在map中的session数据
3. token(令牌)
token 可以解决客户端频繁与服务器验证查询数据库以进行用户名和密码对比
token 是一个加密字符串,可以作为鉴别用户的唯一标识,一般长这样:
426648ef200b455684cb15d6523a935e.d86c828583c5c6160e8acfee88ba1590
- token 是在服务端生成的,前端使用axios携带 用户名/密码 向后端发送登录请求
- 服务端收到 用户名/密码 与数据库进行认证,若成功,服务端会返回一个 token 给前端
- 前端获取到 token 后可以暂时存放到 cookie
- 前端需要手动配置一个 axios 的 request拦截器,将 token 添加到请求头
- 以后的每次请求都会带上 token,由后端判断当前登录用户的权限是否合法
- 如果把这个 token 在服务端持久化(如存入数据库),那它将是一个永久的身份令牌
一般的生成 token
- 可以用设备号/设备mac地址作为token
- 可以用session值作为token
- 生成 token
//生成token
String token = UUID.randomUUID().toString();
- 在服务器端保存token为session
session.setAttribute("token",token);
- 在面页前端保存,使每次发请求都带上
<form>
<input name="token" value="<%=token%>"/>
</form>
- 在handler方法里添加对比代码
//获取服务器的token
String token01 = session.getAttribute("token");
//获取前端的token
String token02 = request.getParameter("token");
//对比
if(token01.equals(token02)){
//处理请求
}else{
//拒绝请求
}
实际开发中使用 JWT 生成 token,其组成形式为: header.payload.signature
- header(标头):由令牌类型(JWT)和所用签名算法组成,并使用base64编码
//header部分,对其进行base64编码
{
"alg": "HS256",
"typ": "JWT"
}
- payload(载荷):声明相关用户的非敏感信息,并使用base64编码
//payload部分,对其进行base64编码
{
"name": "zhangsan",
"admin": true
}
- signature:使用header中指定的签名算法(HS256)进行签名,保证JWT未被篡改