Go语言中如何确保Cookie数据的安全传输
来源:脚本之家
时间:2023-01-07 12:07:54 416浏览 收藏
本篇文章向大家介绍《Go语言中如何确保Cookie数据的安全传输》,主要包括Cookie、数据传输,具有一定的参考价值,需要的朋友可以参考一下。
什么是Cookie
Cookie(也叫Web Cookie或浏览器Cookie)是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。Cookie使基于无状态的HTTP协议记录稳定的状态信息成为了可能。
Cookie主要用于以下三个方面:
- 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
- 个性化设置(如用户自定义设置、主题等)
- 浏览器行为跟踪(如跟踪分析用户行为等)
Go语言如何表示Cookie
在Go的net/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. // MaxAge0 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 }
Name和Value字段就不多说了,单独针对几个需要解释的字段进行说明。
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中的敏感数据量。不要存储用户密码之类的东西,并确保任何编码数据也没有此信息。在某些情况下,开发人员在不知不觉中将敏感数据存储在Cookie或JWT中,因为它们是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更重要。
以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于Golang的相关知识,也可关注golang学习网公众号。
-
137 收藏
-
142 收藏
-
244 收藏
-
119 收藏
-
137 收藏
-
165 收藏
-
473 收藏
-
377 收藏
-
384 收藏
-
246 收藏
-
110 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 507次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 484次学习
-
- 激动的硬币
- 赞 👍👍,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,看完之后很有帮助,总算是懂了,感谢作者分享博文!
- 2023-02-28 22:06:24
-
- 慈祥的歌曲
- 很棒,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,帮助很大,总算是懂了,感谢博主分享文章内容!
- 2023-01-20 08:13:26
-
- 懦弱的睫毛膏
- 这篇技术贴太及时了,作者大大加油!
- 2023-01-20 00:04:10
-
- 强健的芹菜
- 很详细,已加入收藏夹了,感谢作者的这篇文章,我会继续支持!
- 2023-01-19 15:59:54
-
- 追寻的红牛
- 好细啊,已收藏,感谢up主的这篇文章,我会继续支持!
- 2023-01-19 03:07:43
-
- 和谐的山水
- 这篇博文真是及时雨啊,太详细了,赞 👍👍,码起来,关注楼主了!希望楼主能多写Golang相关的文章。
- 2023-01-11 18:54:42
-
- 热心的仙人掌
- 这篇博文真是及时雨啊,up主加油!
- 2023-01-10 17:10:01
-
- 落寞的白猫
- 太细致了,收藏了,感谢博主的这篇技术贴,我会继续支持!
- 2023-01-10 05:58:59
-
- 着急的冰棍
- 这篇技术贴真是及时雨啊,太详细了,很有用,收藏了,关注楼主了!希望楼主能多写Golang相关的文章。
- 2023-01-10 04:10:46
-
- 淡然的蜜粉
- 这篇技术贴出现的刚刚好,好细啊,感谢大佬分享,已加入收藏夹了,关注作者了!希望作者能多写Golang相关的文章。
- 2023-01-09 06:15:01
-
- 自然的大炮
- 赞 👍👍,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,看完之后很有帮助,总算是懂了,感谢作者分享技术贴!
- 2023-01-08 23:15:41