set-cookie 和 cookie 的区别_Go Web 编程如何确保Cookie数据的安全传输

什么是Cookie

Cookie(也叫Web Cookie或浏览器Cookie)是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。Cookie使基于无状态的HTTP协议记录稳定的状态信息成为了可能。

Cookie主要用于以下三个方面:

  • 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)

  • 个性化设置(如用户自定义设置、主题等)

  • 浏览器行为跟踪(如跟踪分析用户行为等)

Go语言如何表示Cookie

Gonet/http库中使用http.Cookie结构体表示一个Cookie数据,调用http.SetCookie函数则会告诉终端用户的浏览器把给定的http.Cookie值设置到浏览器Cookie里,类似下面:

func someHandler(w http.ResponseWriter, r *http.Request) {
  c := http.Cookie{
    Name: "UserName",
    Value: "Casey",
  }
  http.SetCookie(w, &c)
}

http.Cookie结构体类型的定义如下:

type Cookie struct {
   Name  string
   Value string

   Path       string    // optional
   Domain     string    // optional
   Expires    time.Time // optional
   RawExpires string    // for reading cookies only

   // MaxAge=0 means no 'Max-Age' attribute specified.
   // MaxAge<0 means delete cookie now, equivalently 'Max-Age: 0'
   // MaxAge>0 means Max-Age attribute present and given in seconds
   MaxAge   int
   Secure   bool
   HttpOnly bool
   SameSite SameSite
   Raw      string
   Unparsed []string // Raw text of unparsed attribute-value pairs
}

NameValue字段就不多说了,单独针对几个需要解释的字段进行说明。

Domain

默认值是当前正在访问的Host的域名,假设我们现在正在访问的是www.example.com,如果需要其他子域名也能够访问到正在设置的Cookie值的话,将它设置为example.com 。注意,只有正在被设置的Cookie需要被其他子域名的服务访问到时才这么设置。

c := Cookie{
  ......
  Domain: "example.com",
}

Path

设置当前的 Cookie 值只有在访问指定路径时才能被服务器程序读取。默认为服务端应用程序上的任何路径,但是您可以使用它限制为特定的子目录。例如:

c := Cookie{
  Path: "/app/",
}

Secure

标记为Secure 的Cookie只应通过被HTTPS协议加密过的请求发送给服务端。但即便设置了 Secure 标记,敏感信息也不应该通过Cookie传输,因为Cookie有其固有的不安全性,Secure标记也无法提供确实的安全保障。从 Chrome 52 和 Firefox 52 开始,不安全的站点(http:)无法使用Cookie的 Secure 标记。

HttpOnly

为避免跨域脚本 (XSS) 攻击,通过JavaScript的API无法访问带有 HttpOnly 标记的Cookie,它们只应该发送给服务端。如果包含服务端Session 信息的Cookie 不想被客户端JavaScript 脚本调用,那么就应该为其设置 HttpOnly 标记。

安全地传输Cookie

接下来我们探讨两种安全传输Cookie的方法

对Cookie数据进行数字签名

对数据进行数字签名是在数据上添加“签名”的行为,以便可以验证其真实性。不需要对数据进行加密或屏蔽。

签名的工作方式是通过散列-我们对数据进行散列,然后将数据与数据散列一起存储在Cookie中。然后,当用户将Cookie发送给我们时,我们再次对数据进行哈希处理,并验证其是否与我们创建的原始哈希匹配。

我们不希望用户也用篡改后的数据创建新的哈希,因此经常会看到使用HMAC之类的哈希算法,以便可以使用密钥对数据进行哈希。这样可以防止最终用户同时编辑数据和数字签名(哈希)。

JWT也是使用的这种数字签名的方式进行传输的。

上面的数据签名过程并不需要我们自己去实现,我们可以在Go中使用gorilla/securecookie的程序包来完成此操作,在该程序包中,你可以在创建SecureCookie时为其提供哈希密钥,然后使用该对象来保护你的Cookie

对`Cookie`数据进行签名:

//var s = securecookie.New(hashKey, blockKey)
var hashKey = securecookie.GenerateRandomKey(64)
var s = securecookie.New(hashKey, nil)

func SetCookieHandler(w http.ResponseWriter, r *http.Request) {
  encoded, err := s.Encode("cookie-name", "cookie-value")
  if err == nil {
    cookie := &http.Cookie{
      Name:  "cookie-name",
      Value: encoded,
      Path:  "/",
    }
    http.SetCookie(w, cookie)
    fmt.Fprintln(w, encoded)
  }

解析被签名的 Cookie:

func ReadCookieHandler(w http.ResponseWriter, r *http.Request) {
  if cookie, err := r.Cookie("cookie-name"); err == nil {
    var value string
    if err = s.Decode("cookie-name", cookie.Value, &value); err == nil {
      fmt.Fprintln(w, value)
    }
  }
}

注意这里的Cookie数据未加密,仅仅是被编码了,任何人都可以把Cookie数据解码回来。

加密Cookie 数据

每当将数据存储在Cookie中时,请始终尽量减少存储在Cookie中的敏感数据量。不要存储用户密码之类的东西,并确保任何编码数据也没有此信息。在某些情况下,开发人员在不知不觉中将敏感数据存储在CookieJWT中,因为它们是base64编码的,但实际上任何人都可以解码该数据。它已编码,未加密。

这是一个很大的错误,因此,如果你担心意外存储敏感内容,建议 你使用gorilla/securecookie之类的软件包。

之前我们讨论了如何将其用于对Cookie进行数字签名,但是securecookie也可以用于加密和解密Cookie数据,以使其无法轻松解码和读取。

要使用该软件包加密Cookie,只需在创建SecureCookie实例时传入一个blockKey即可。

将上面签名Cookie的代码片段进行一些小改动,其他地方完全不用动,securecookie包会帮助我们进行Cookie的加密和解密:

var hashKey = securecookie.GenerateRandomKey(64)
var blockKey = securecookie.GenerateRandomKey(32)
var s = securecookie.New(hashKey, blockKey)

总结

今天的文章除了阐述如何使用Go语言安全地传输Cookie数据外,再次格外强调一遍,编码和加密的不同,从数据可读性上看,两者差不多,但本质上是完全不一样的:

  • 编码使用公开可用的方案将数据转换为另一种格式,以便可以轻松地将其反转。

  • 加密将数据转换为另一种格式,使得只有特定的个人才能逆转转换。

我们在做数据传输时一定要记住两者的区别,某种意义上,我觉得记住这两点的区别比你学会今天文章里怎么安全传输Cookie更重要。

推荐阅读

  • Go Web编程--使用Go语言创建静态文件服务器


喜欢本文的朋友,欢迎关注“Go语言中文网”:

2501721ab6abb2bd61ad71ebd290e244.png

Go语言中文网启用微信学习交流群,欢迎加微信:274768166,投稿亦欢迎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/297132.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用C#快速生成顺序GUID

前言通常&#xff0c;我们采用数值ID(long)/GUID作为全局唯一标识符。但是&#xff0c;在多线程、高并发情况下&#xff0c;由应用程序生成数值ID容易产生重复&#xff0c;而由数据库生成又会造成性能瓶颈。而使用Guid.NewGuid()生成的GUID虽然不会重复&#xff0c;但是它是无序…

带你见识世界的5部纪录片(免费领取)

全世界只有3.14 % 的人关注了爆炸吧知识纪录片一直都是增长见识又带给你力量的东西&#xff0c;你可能忙于学业、生活、工作而不能行万里路&#xff0c;但至少你还可以看纪录片&#xff0c;从一方屏幕看到整个世界。今天就为大家整理了5部高分纪录片&#xff0c;文末附领取方式…

Android简明开发教程二十一:访问Internet 绘制在线地图

在例子Android简明开发教程十七&#xff1a;Dialog 显示图像 中我们留了一个例子DrawMap()没有实现&#xff0c;这个例子显示在线地图&#xff0c;目前大部分地图服务器都是将地图以图片存储以提高响应速度。 一般大小为256X256个像素。具体可以参见离线地图下载方法解析 。 比…

url采集工具_大数据关键技术浅谈之大数据采集

在前几篇文章中&#xff0c;企通查为大家介绍了大数据处理的基本流程。从大数据的一系列处理过程中&#xff08;抽取、集成、分析、解释&#xff09;&#xff0c;我们可以发现这一整套流程中涵盖了数据存储、处理、应用等多方面的技术。大数据价值的完美体现需要多种技术的协同…

使用 WPF + Chrome 内核实现 在线客服系统 的复合客服端程序

本系列文章详细介绍使用 .net core 和 WPF 开发 升讯威在线客服与营销系统 的过程。本产品已经成熟稳定并投入商用。免费使用 & 私有化部署免费下载&#xff1a;https://docs.shengxunwei.com/Post/f7bc8496-14ee-4a53-07b4-08d8e3da6269视频实拍&#xff1a;演示升讯威在线…

abp框架java,【Net】ABP框架学习之正面硬钢

前言本文介绍另一种学习ABP框架的方法&#xff0c;该方法为正面硬钢学习法。。。我们不去官网下载模板&#xff0c;直接引用DLL&#xff0c;直接使用。WebApi项目创建首先创建一个WebApi项目&#xff0c;结构如下。然后Nuget搜索ABP&#xff0c;安装ABP框架。(我这里安装的是5.…

不同对象的通话是时长​

1 一个专门为某人打造的形容词2 当代人的手机铃声3 “可以吃宵夜吗”“不行” 4 好可爱&#xff01;&#xff01;&#xff01;5 这不是道具&#xff0c;是真的红酒杯里倒着红酒叠在硬币上&#xff01;6 这14个未接电话就很有灵性了&#xff01;7 你觉得以下哪个事件给你的痛苦感…

poj 1088 滑雪 详解

http://poj.org/problem?id1088 这是一道dp入门题&#xff0c;不过我一直没想明白应该怎么dp。今天&#xff0c;在做自己学校oj的算法基础题时看到这题&#xff0c;标注着dp的分类&#xff0c;加上我一直都比较喜欢做dp题&#xff0c;于是我就决心今晚要把这道入门题切了。 题…

python find函数_Python 速学!不懂怎么入门python的小白看这篇就够了!

Python是一种非常流行的脚本语言&#xff0c;而且功能非常强大&#xff0c;几乎可以做任何事情&#xff0c;比如爬虫、网络工具、科学计算、树莓派、Web开发、游戏等各方面都可以派上用场。同时无论在哪种平台上&#xff0c;都可以用 Python 进行系统编程。本文讨论基本的 Pyth…

前端开发的盛宴

想写这篇文章由来已久&#xff0c;目的是想回顾一下基于Web技术的开发技术和流程的变迁&#xff0c;以及其背后的原因或规律。我依然记得&#xff0c;很多年前做出来第一个公司网站时的激动心情&#xff08;加班到晚上&#xff0c;兴奋地在空旷的办公室走来走去&#xff09;&am…

datav本地部署 java,Spring Boot对Spring Data JPA的自动配置

一 点睛Spring Boot对Spring Data JPA的自动配置放置在如下路径&#xff1a;二 源码分析1 JpaRepositoriesAutoConfiguration类分析ConfigurationConditionalOnBean(DataSource.class)ConditionalOnClass(JpaRepository.class)ConditionalOnMissingBean({ JpaRepositoryFactory…

靠拿奖学金完成学业后,博士生为女友放弃年薪30万工作选择留校任教

全世界只有3.14 % 的人关注了爆炸吧知识“相恋八年&#xff0c;一路陪伴。研究生毕业后&#xff0c;博士生决定为女友放弃年薪30万的工作选择留校任教&#xff0c;因为曾和女友约定一起当老师。好的科研爱情&#xff0c;或许就是这样携手前进。索长友是哈尔滨理工大学的博士生&…

小菜学设计模式——观察者模式

2019独角兽企业重金招聘Python工程师标准>>> 背景 上一次去看电影院看电影&#xff0c;半旁边的妹子说只要扫一扫就能免费领取爆米花一份&#xff0c;你说我怎么躲得过妹子的招数呢&#xff1f;所以拿起我的手机&#xff0c;扫一扫&#xff0c;注册会员&#xf…

获取 子文件夹 后缀_CSDN学院第一个Ptython Homework-- 递归统计文件夹大小

作业:通过第一周学习的内容,自主编写一个py文件,能够递归文件夹大小,并将统计后的大小进行格式化输出.作业体现形式:以代码的方式保存成后缀为py的脚本.作业的注意事项:1.文件名命名规范.2.注释清晰.3.运行结果符合预期效果 .思路提示:1.使用python内置的os模块来进行文件相关的…

java 链表逆序 递归,java用递归和非递归实现链表逆序

传统的逆序链表方法是使用三个指针来记录节点的状态&#xff0c;防止链表断裂。Node节点public class Node {private int data;private Node next;public Node(int data){this.data data;next null;}public int getData() {return this.data;}public void setData(int data) …

史上最硬核老师:17年间,拿着菜刀把400个混混送进了哈佛耶鲁麻省!

全世界只有3.14 % 的人关注了爆炸吧知识今天&#xff0c;来给大家介绍一位硬核教师Jaime Escalante——手握杰斐逊奖、自由精神奖&#xff0c;拿着菜刀把400个混混送进了哈佛耶鲁麻省。海梅斯埃斯卡兰特(Jaime Escalante)初出茅庐1930年12月31日&#xff0c;Jaime出生于玻利维亚…

数据库表设计

数据库表设计 分析上述各实体的属性集&#xff0c;从中找出关系的主键&#xff0c;然后用关系式来表示实体(其中下划线的属性为主键)。表4-1至表4-5分别给出了主要表结构各实体的属性如下&#xff1a; 表4-1 admin 表名称 主要字段 数据类型 长度 属性 输入方式 描述 …

抓包写代码模拟怎么减少重复劳动

由于工作需要会经常需要Fiddler抓包Chrome F12抓包然后根据抓包写代码来模拟&#xff0c;一般来说我都是先抓包&#xff0c;打开postman把抓来的包放到postman里面模拟请求然后利用PostMan的生成代码功能大部分的Reponse都是Json&#xff0c;为了方反列化接着要打开一个在线工具…

机械史上最复杂的巅峰之作,这才是最强大脑!

全世界只有3.14 % 的人关注了爆炸吧知识今天我们来认识一下机械史上最强大脑&#xff1a;英国数学家查尔斯巴贝奇&#xff0c;他是可编程计算机的发明者&#xff0c;计算机的先驱。他设计过的计算机器有差分机、分析机和第二个差分机。差分机可谓是机械史最复杂的巅峰之作。在英…

mybatis-plus 会自动增加 order by_python自动撸支付宝基金答题红包

python自动撸支付宝基金答题红包背景在一个套利撸羊毛群里&#xff0c;一群小伙伴每天在不懈地撸支付宝的基金红包&#xff0c;于是自己也加入了撸红包大军。于是就重复地在不同的基金里面&#xff0c;看有没有答题红包&#xff0c;有的话就点进去&#xff0c;回答一个及其容易…