Java小白入门 —— Session、Cookie 和 Token
一. Cookie 技术:
1. 什么是 cookie ?
Cookie 实际上是一小段的文本信息(key-value格式)。当客户端向服务端发起请求时,如果需要记录客服端的用户状态时,服务端就会使用 response 向客户端浏览器颁发一个 Cookie 凭证,客户端浏览器会将此凭证存储下来,当再次访问服务端时,客户端会将 Cookie 携带一起访问,服务端拿到 Cookie 便能知道访问的用户状态。
2. 特点:
Cookie 技术会将会话技术保存在浏览器客户端。
3. Cookie 技术核心:
API | 描述 |
---|---|
setMaxAge() | 设置维持Cookie的时间和方式 |
setName(),setValue() | 设置Cookie的内容 |
getName(), getValue() | 得到Cookie信息的内容 |
setPath(“web应用的路径”) | 设置Cookie的有效路径,不设置的话,默认情况在当前的web应用路径下 |
步骤:
1. 构造 Cookie 对象:
Cookie (String name,String value)
2. 这是 Cookie 属性:
void setPath(url):设置 Cookie 的有效访问路径;
void setMaxAge(expiry):设置 Cookie 的有效时间;
void setValue(newValue):设置 Cookie 的值。
3. 发送 Cookie 到浏览器保存:
void response.addCookie(cookie):发送 Cookie。
4. 服务端接收 Cookie:
Cookie[] request.getCookies():接收 Cookie。
4. 局限:
Cookie 只能存字符串类型,不能保存对象;
只能存非中文;
1个 Cookie 的容量不能超过 4KB;
5. 案例:
显示用户上一次的访问时间
/**
* @author MuXin
* @date 2020/10/28 15:46
*/
@WebServlet("/lastLogin")
public class CookieDemo extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");//设置头文件,防止浏览器显示乱码
String lastTime = null;
//接收 Cookie
Cookie[] cookies = req.getCookies();
for (Cookie cookie : cookies) {
String name = cookie.getName();
if (name.equals("lastLogin")) {
lastTime = cookie.getValue();
break;
}
}
if (StringUtils.isEmpty(lastTime)) {
resp.getWriter().println("当前为首次访问!");
} else {
resp.getWriter().println("上一次访问时间为:" + lastTime);
}
//保存访问时间
//创建 Cookie 将当前时间设置到 Cookie 信息中,并保存到浏览器中
String time = new SimpleDateFormat("yyyy-mm-dd-hh:mm:ss").format(new Date());
Cookie cookie1 = new Cookie("lastTime", time);
cookie1.setMaxAge(60 * 60 * 24);
//发送 Cookie
resp.addCookie(cookie1);
}
}
运行结果:
可能遇到的问题:
原因:由于 Tomcat 版本过高,无法识别 “空格符号”,将代码中的空格符号替换即可。
二. Session 技术:
1. 特点:
不仅可保存字符串类型,也能保存对象;
容量大;
会话数据保存在服务器端(内存中)
2. Session 核心技术:
API | 描述 |
---|---|
getId() | 获取 sessionId |
setMaxInactiveInterval(int var1) | 设置超时时间 |
getMaxInactiveInterval() | 获取超时时间 |
setAttribute(String var1, Object var2) | 设置 session 属性 |
getAttribute(String var1) | 获取 session 属性 |
getAttributeNames() | 获取 session 所有的属性 |
removeAttribute(String var1) | 删除 session 属性 |
getCreationTime() | 获取 session 的创建时间 |
getLastAccessedTime() | 获取 session 最后活跃的时间 |
isNew() | session 是否是新的 |
invalidate() | 销毁 session |
步骤:
- 创建或得到 Session 对象
HttpSession getSession(); - 设置 Session 对象
getId() //获取 sessionId
void setMaxInactiveInterval(int interval) //设置超时时间
void invalidate() //销毁 session 对象 - 保存会话数据到 Session 对象
void setAttribute(String name, Object value) //设置 session 属性
Object getAttribute(String name) //获取 session 属性
void removeAttribute(String name) //清除数据
3. Session 原理:
当客户端第一次访问服务端时,进行创建 Session 对象,并给 Session 对象分配一个唯一 JSESSIONID,服务器会将这个 JSESSIONID作为凭证放到 Cookie 中返回到客户端,客户端保存的只是这个 JSESSIONID(凭证);
当客户端第二次访问服务端时,浏览器会带着 JSESSIONID 访问服务器,服务器接收到 JSESSIONID 后会去内存中搜索是否存放有对应 Session 对象;
如果找到,返回对应 Session 对象,如果没有,则重新分配对象并返回 JSESSIONID。
4. Session 和 Cookie 的区别:
Session | Cookie | |
---|---|---|
存储位置 | 浏览器存凭证,服务器存 Session 对象 | 浏览器 |
安全性 | 安全 | 可以分析本地 Cookie 进行 Cookie 欺骗,不安全 |
存储数据量 | 没有限制 | 不超过 4KB ,并且很多浏览器都限制一个站点最多保存20个 Cookie |
存储数据方式 | 可以存储对象 | 只能存字符串 |
性能 | 占用服务器性能 | 存放在浏览器,不占用服务器性能 |
三. Token 技术:
1. 什么是 Token?
token其实就是一个令牌,具有随机性,类似于sessionId;在对接一些第三方平台的时候,为了能够保证数据安全性,通常会使用一些令牌进行交互。
2. Token 的特点:
Token 是在服务端产生的。如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回 Token 给前端。前端可以在每次请求的时候带上 Token 证明自己的合法地位。如果这个 Token 在服务端持久化(比如存入数据库),那它就是一个永久的身份令牌。
Token 完全由应用管理,所以它可以避开同源策略;
Token 可以避免 CSRF 攻击;
Token 可以是无状态的,可以在多个服务间共享;
3. 基于 Token 的身份认证:
- 客户端使用用户名跟密码请求登录;
- 服务端收到请求,去验证用户名与密码;
- 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端;
- 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里;
- 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token;
- 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据;
- APP登录的时候发送加密的用户名和密码到服务器,服务器验证用户名和密码,如果成功,以某种方式比如随机生成32位的字符串作为token,存储到服务器中,并返回token到APP,以后APP请求时;
- 凡是需要验证的地方都要带上该token,然后服务器端验证token,成功返回所需要的结果,失败返回错误信息,让他重新登录。其中服务器上token设置一个有效期,每次APP请求的时候都验证token和有效期。