Cookie 指得是储存在Client (用户)端上的资料,是一种在服务器与浏览器之间交换讯息的方法,按照Client 端储存的位置可分为记忆体Cookie 和硬碟Cookie。
记忆体Cookie 由浏览器维护,储存在记忆体中,浏览器关闭即消失,存在时间短暂,也称为非持久Cookie;硬碟Cookie 储存在硬碟里,有过期时间,除非使用者手动清理或到了过期时间,否则硬碟Cookie 不会清除,存在时间较长,也称为为持久Cookie。
因为HTTP 协定是无状态的,Server 不知道使用者上一次做了什麽,这严重阻碍了互动式Web 应用程序的实现,所以Cookie 就是用来绕开HTTP 的无状态性的一种手段,Server 可以设定或读取Cookie 中包含的资讯,藉此维护使用者跟Server 对谈中的状态。
若要在Spring Boot 中设置Cookie,就要使用到HttpServletResponse 的addCookie() 方法,该方法就是将一个Cookie 物件加入Response 中。
@RequestMapping(value = "/setCookie", method = RequestMethod.GET)
public String setCookie(HttpServletResponse response) {
// 建立一个Cookie 物件
Cookie cookie = new Cookie("username", "kaijun");
// 设置过期时间,若无设置时间,其生命周期将持续到Session 过期为止
cookie.setMaxAge(7*24*60*60);
// 将Cookie 物件加入Response 中
response.addCookie(cookie);
return "add Cookie";
}
Spring 框架提供了@CookieValue
注释来取得Cookie 的值,其参数 value
为Cookie 名称,可使用参数 defaultValue
设定预设值,若没有预设值也查无Cookie 名称则会抛出IllegalStateException 例外。
@RequestMapping(value = "/getCookie", method = RequestMethod.GET)
public String getCookie(@CookieValue(value = "username") String username) {
return "Hello! " + username;
}
在实务上我们可能不只有一个Cookie,若要使用@CookieValue 一个一个取得会使得程序码变得冗长,所以可以使用HttpServletRequest 的getCookies() 方法一次取得所有Cookie。
@RequestMapping(value = "/getCookies", method = RequestMethod.GET)
public String getCookies(HttpServletRequest request) {
Cookie[] cookies = request.getCookies();
if (cookies != null) {
return Arrays.stream(cookies)
.map(c -> c.getName() + "=" + c.getValue())
.collect(Collectors.joining(", "));
}
return "No cookies";
}
我们可以指定Cookie 仅能透过加密的HTTPS 连结发送Cookie 到服务器,无法透过未加密的HTTP 连接传送。
// 改写上面setCookie 方法
@RequestMapping(value = "/setCookie", method = RequestMethod.GET)
public String setCookie(HttpServletResponse response) {
// 建立一个Cookie 物件
Cookie cookie = new Cookie("username", "kaijun");
// 设置过期时间,若无设置时间,其生命周期将持续到Session 过期为止
cookie.setMaxAge(7*24*60*60);
// 设置HTTPS 安全的Cookie
cookie.setSecure(true);
// 将Cookie 物件加入Response 中
response.addCookie(cookie);
return "add Cookie";
}
HttpOnly Cooke 是用於防止跨站点脚本攻击(XSS),也就是设置了HttpOnly 的Cookie 无法透过JavaScript 的Document.cookieAPI 访问服务器。
// 再改写上面setCookie 方法
@RequestMapping(value = "/setCookie", method = RequestMethod.GET)
public String setCookie(HttpServletResponse response) {
// 建立一个Cookie 物件
Cookie cookie = new Cookie("username", "kaijun");
// 设置过期时间,若无设置时间,其生命周期将持续到Session 过期为止
cookie.setMaxAge(7*24*60*60);
// 设置HTTPS 安全的Cookie
cookie.setSecure(true);
// 设置为不能被JS 访问的Cookie
cookie.setHttpOnly(true);
// 将Cookie 物件加入Response 中
response.addCookie(cookie);
return "add Cookie";
}
到了最後不需要Cookie 值时,应该将其删除以释放记忆体资源,要删除Cookie 需要将Cooke 值设为null 并将过期时间设置为0。
@RequestMapping(value = "/deleteCookie", method = RequestMethod.GET)
public String deleteCookie(HttpServletResponse response) {
// 将Cookie 值设置为null
Cookie cookie = new Cookie("username", null);
// 设置过期时间为0
cookie.setMaxAge(0);
// 将Cookie 物件加入Response 中
response.addCookie(cookie);
return "delete Cookie";
}
Cookie - 维基百科,自由的百科全书
如何在SpringBoot中使用Cookies
资料分类是评估资料的业务价值或其重要性和对利益相关者的意义,以确定适当的保护级别的过程。可以从各种角...
Architecture Components 以前 Android Developers 网站没有...
前言 时间终於过到了最後一天,昨天看了三个特别的虚拟文件系统,今天就看看实际存在的文件管理系统吧! ...
识别威胁 在前面的概论中,我们知道威胁是外来的,他必须配合资产才会产生风险,所以资产与威胁是相互之...
前言 list 是 Python 中最常见的资料类型,有许多的应用都会用到 list 喔! 今天会先...