如何在 SpringBoot 中使用 cookies

如何在 SpringBoot 中使用 cookies

原文: https://attacomsian.com/blog/cookies-spring-boot#further-reading

  • 读 HTTP Cookie
  • 设置 HTTP Cookie
  • 读 All Cookies
  • Cookie 的有效期
  • Secure Cookie
  • HttpOnly Cookie
  • Cookie Scope (范围)
  • 删除 Cooke
  • 总结

HTTP Cookie(也称为web Cookie、浏览器Cookie)是服务器存储在用户浏览器中的一小块信息。服务器在返回浏览器请求的响应时设置cookies。浏览器存储cookies,并将它们与下一个请求一起发送回同一服务器。Cookie通常用于会话管理、用户跟踪和存储用户首选项。

Cookies帮助服务器跨多个请求记住客户机。如果没有cookies,服务器将把每个请求都当作一个新的客户机来处理。

在本教程中,我们将学习如何在SpringBoot应用程序中读取、设置和删除httpcookies。

Reading HTTP Cookie

Spring框架提供@CookieValue注释来获取任何http cookie的值,而无需迭代从请求中获取的所有cookie。此注释可用于将cookie的值映射到控制器方法参数。

@GetMapping("/")
public String readCookie(@CookieValue(value = "username", defaultValue = "Atta") String username) {
    return "Hey! My username is " + username;
}

在上面的代码片段中,请注意defaultValue=“Atta”。如果未设置默认值,Spring将抛出java.lang.IllegalStateException异常在HTTP请求中找不到名为username的cookie时出现异常。

Setting HTTP Cookie

要在Spring Boot中设置cookie,可以使用HttpServletResponse类的addCookie()方法。您所需要做的就是创建一个新的Cookie类实例并将其添加到响应中。

@GetMapping("/change-username")
public String setCookie(HttpServletResponse response) {
    // create a cookie
    Cookie cookie = new Cookie("username", "Jovan");

    //add cookie to response
    response.addCookie(cookie);

    return "Username is changed!";
}

Reading All Cookies

我们也可以使用HttpServletRequest类作为控制器方法参数来读取所有cookie,而不是使用@CookieValue注释。此类提供getCookies()方法,该方法将浏览器发送的所有Cookie作为Cookie数组返回。

@GetMapping("/all-cookies")
public String readAllCookies(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 Expiration

如果没有为cookie指定过期时间,则只要会话未过期,cookie就会持续。这种cookies称为会话cookies。会话Cookie保持活动状态,直到用户关闭浏览器或清除Cookie。上面创建的 username cookie实际上是一个会话cookie。

但是您可以重写此默认行为,并使用cookie类的 setMaxAge()方法设置cookie过期时间。

// create a cookie
Cookie cookie = new Cookie("username", "Jovan");
cookie.setMaxAge(7 * 24 * 60 * 60); // expires in 7 days

//add cookie to response
response.addCookie(cookie);

现在,用户名cookie将在接下来的7天内保持活动状态,而不是在浏览器关闭时过期。这种cookie在指定的日期和时间过期,称为永久cookie。

传递给setMaxAge()方法的过期时间以秒为单位。过期日期和时间是相对于设置cookie的客户端的,而不是相对于服务器的。

Secure Cookie

安全cookie是仅通过加密的HTTPS连接发送到服务器的cookie。安全Cookie不能通过未加密的HTTP连接传输到服务器。

// create a cookie
Cookie cookie = new Cookie("username", "Jovan");
cookie.setMaxAge(7 * 24 * 60 * 60); // expires in 7 days
cookie.setSecure(true);

//add cookie to response
response.addCookie(cookie);

HttpOnly Cookie

HttpOnly Cookie用于防止跨站点脚本(XSS)攻击,不能通过JavaScript 的Document.cookie API 访问。当为cookie设置HttpOnly标志时,它会告诉浏览器只有服务器才能访问此特定cookie。

// create a cookie
Cookie cookie = new Cookie("username", "Jovan");
cookie.setMaxAge(7 * 24 * 60 * 60); // expires in 7 days
cookie.setSecure(true);
cookie.setHttpOnly(true);

//add cookie to response
response.addCookie(cookie);

Cookie Scope

如果未指定作用域,cookie仅发送到用于在浏览器中设置它的路径的服务器。我们可以使用Cookie类的setPath()方法来更改此行为。这将设置cookie的 Path 参数。

// create a cookie
Cookie cookie = new Cookie("username", "Jovan");
cookie.setMaxAge(7 * 24 * 60 * 60); // expires in 7 days
cookie.setSecure(true);
cookie.setHttpOnly(true);
cookie.setPath("/"); // global cookie accessible every where

//add cookie to response
response.addCookie(cookie);

Deleting Cookie

要删除cookie,请将 Max-Age 参数设置为0并重置cookie的值。您还必须传递与设置cookie属性相同的其他cookie属性。不要将Max-Age 参数设置为 -1。否则,浏览器会将其视为会话cookie。

// create a cookie
Cookie cookie = new Cookie("username", null);
cookie.setMaxAge(0);
cookie.setSecure(true);
cookie.setHttpOnly(true);
cookie.setPath("/");

//add cookie to response
response.addCookie(cookie);

Summary

Cookie提供了一种在服务器和浏览器之间交换信息的方法,用于管理会话(登录、购物车、游戏分数)、记住用户偏好(主题、隐私策略接受度)以及跟踪整个站点的用户行为。

springboot提供了一种读取、写入和删除httpcookies的简单方法。

  • @CookieValue注释将cookie的值映射到方法参数。当cookie不可用时,应设置默认值以避免运行时异常。
  • HttpServletResponse类可用于在浏览器中设置新cookie。您只需要创建Cookie类的实例并将其添加到Response中。
  • 要读取所有Cookie,可以使用HttpServletRequest的getCookies()方法,该方法返回一个Cookie数组。
  • Max-Age参数指定cookie过期的日期和时间。
  • 如果在cookie中存储敏感信息,请确保设置Secure和HttpOnly标志以避免XSS攻击。
  • 设置Path=/以使当前域的任何地方都可以访问cookie。
  • 若要删除cookie,请将Max-Age设置为0,并传递用于设置cookie的所有属性。

demo源码:https://github.com/FDzhang/demo-study/tree/master/demo-springboot/demo-cookies

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容