一文带你了解CSRF、Cookie、Session和token,JWT之间的关系

简介: 1.Cookie和Session兄弟由于HTTP协议本身是无状态的,也就是说同一个用户前一次HTTP请求和后一次HTTP请求时相互独立的,无法判断后一次请求的用户是不是刚才的用户。为了记录用户的状态,才有了Cookie。Cookie实际上以key-value键值对的形式存储了一些文本信息数据,它将数据保存在客户端(浏览器)。


1.Cookie和Session兄弟


由于HTTP协议本身是无状态的,也就是说同一个用户前一次HTTP请求和后一次HTTP请求时相互独立的,无法判断后一次请求的用户是不是刚才的用户。为了记录用户的状态,才有了Cookie。Cookie实际上以key-value键值对的形式存储了一些文本信息数据,它将数据保存在客户端(浏览器)。


当浏览器(客户端)登陆网站请求服务器后,服务器的response中返回了Set-Cookie(与Cookie类似,也是键值对的一小段文本),浏览器(客户端)将这个Cookie保存起来,当下次该浏览器(客户端)再请求此服务器时,浏览器(客户端)把请求的网址连同该域的Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。


需要注意的是,由于同源策略的存在,不同源的网站不能使用对方网站的Cookie,也即是不可以跨域名的,隐私安全机制禁止网站非法获取其他网站的Cookie。所以,在CSRF中恶意网站其实并不能获取到信任网站的Cookie💢


Cookie和session是配套使用的。Cookie是将一些文本信息以键值对的形式保存在客户端,而Session是将某些信息保存在服务器端。因为HTTP协议是无状态,Cookie是在客户端实现状态保持,Session是在服务器端实现状态保持,通过两者的结合实现客户端和服务器连接的状态保持。那么如何才能将Cookie对应到正确的Session呢?利用sessionid。通常在数据库中有一个seesion表,存放着所有的Session数据,大家都知道数据库数据都有一个id,而sessionid就对应的这个id,所以通过浏览器传递过来的Cookie,服务器能找到对应id的Session实现连接的状态保持。


那么,为什么有了cookie还需要session呢?💥


用session只需要在客户端保存一个id,实际上大量数据都是保存在服务端。如果全部用cookie,数据量大的时候客户端是没有那么多空间的。

cookie只是实现session的其中一种方案。虽然是最常用的,但并不是唯一的方法。

全部在客户端保存,服务端无法验证,这样伪造和仿冒会更加容易。(伪造一个随机的id很难,但伪造另一个用户名是很容易的)

全部保存在客户端,那么一旦被劫持,全部信息都会泄露

客户端数据量变大,网络传输的数据量也会变大


2.更厉害的Token


token技术可以让服务器完全不用保存任何登录信息


token的流程是这样的。客户端登录通过后,服务器生成一堆客户端身份信息,包括用户名、用户组、有那些权限、过期时间等等。另外再对这些信息进行签名。之后把身份信息和签名作为一个整体传给客户端。这个整体就叫做token。之后,客户端负责保存该token,而服务器不再保存。客户端每次访问该网站都要带上这个token。服务器收到请求后,把它分割成身份信息和签名,然后验证签名,若验证成功,就直接使用身份信息(用户名、用户组、有哪些权限等等)


可以看出,相对于cookie/session机制,token机制中,服务器根本不需要保存用户的身份信息(用户名、用户组、权限等等)。这样就减轻了服务器的负担💟


我们举个例来说,假如目前有一千万个用户登录了,在访问不同的网页。如果用cookie/session,则服务器内存(或内存数据库)中要同时记录1千万个用户的信息。每次客户端访问一个页面,服务器都要从内存中查询出他的登录信息。而如果用token,则服务器内存中不记录用户登录信息。它只需要在收到请求后,直接使用客户端发过来的登录身份信息。


可以这么说,cookie/session是服务器说客户端是谁,客户端才是谁。而token是客户端说我(客户端)是谁,我就是谁。当然了,token是有签名机制的。要是客户端伪造身份,签名通不过。这个签名算法很简单,就是将客户端的身份信息加上一个只有服务器知道的盐值(不能泄露),然后进行md5散列算法(这里只是简化,方便理解,实际细节要稍复杂一些)


token因为服务器不保存用户身份信息,一切都依赖当初那个签名。所以存在被盗用的风险。也就是说一旦盗用,服务器可能毫无办法,因为它只认签名算法。而session机制,服务器看谁不爽,可以随时把他踢出(从内存中删掉)。正是因为如此,token高度依赖过期时间。过期时间不能太长。过期短,可以减少被盗用的风险😎


除了上面所说的,如果开发的系统足够小,倾向于使用cookie/session。如果系统同时登录用户多,集群服务器多,有单点登录需求,则倾向于使用token。


3.大恶魔CSRF


CSRF (Cross-site Request Forgery),中文名称:跨站伪造。危害是攻击者可以盗用你的身份,以你的名义发送恶意请求。比如可以盗取你的账号,以你的身份发送邮件,购买商品等。


客户端和淘宝断开连接后,但是客户端保存着淘宝给的cookie,这个记录着客户端的信息,用于确认客户端本人,但是钓鱼网站,给客户端发链接,让它点击了该链接进入一个页面,这个钓鱼页面里面可能写了如下代码:


<img src='http://www.taobao.com/action?k1=v1&k2=v2' width=0 height=0 />


这里width=0 height=0 表示图片是不可见的。这个语句会导致客户端浏览器器向另外的服务器(淘宝)发送一个请求。


因为浏览器不管该图片url实际是否指向一张图片,只要src字段中规定了url,就会按照地址触发这个请求。(浏览器默认都是没有禁止下载图片,这是因为禁用图片后大多数web程序的可用性就会打折扣)。加载图片根本不考虑所涉及的图像所在位置(可以跨域)。如果A网站不小心提供了get接口就非常不幸得中招了


意思是,客户端打开了钓鱼网站,却在不知情的情况下,发送了一个请求给淘宝,这个请求有可能是转账,付款等等,因为是客户端发出的请求,所以客户端会带上自己的cookie,这样就可以请求成功


4.Token预防CSRF


比如要进行转账的操作,服务器端会要求客户端传递token,如果是正常的转账操作,没问题


但是如果是点击钓鱼网站,然后触发向服务器端发出转账请求,这个请求是已经提前写好了放在钓鱼网站里面,它只能让客户端访问,取不到cookie,更取不到token,所以在请求中就明确要求写明放在cookie里面的token,就可以了


比如在银行里转账,银行页面上的转账请求链接,是银行服务器那边生成的链接,所以那边是可以在请求里面就加上你客户端的token的,但是钓鱼网站无法得到你的token,钓鱼网站仿造的转账请求链接是无法把token写入的,所以就无法生效


5.为什么要选择Token技术


token相对cookie的优势


无状态


基于token的验证是无状态的,这也许是它相对cookie来说最大的优点。后端服务不需要记录token。每个令牌都是独立的,包括检查其有效性所需的所有数据,并通过声明传达用户信息。

服务器唯一的工作就是在成功的登陆请求上签署token,并验证传入的token是否有效。


多站点使用


cookie绑定到单个域。foo.com域产生的cookie无法被bar.com域读取。使用token就没有这样的问题。这对于需要向多个服务获取授权的单页面应用程序尤其有用。

使用token,使得用从myapp.com获取的授权向myservice1.com和myservice2.com获取服务成为可能。


支持移动平台


好的API可以同时支持浏览器,iOS和Android等移动平台。然而,在移动平台上,cookie是不被支持的。


性能


一次网络往返时间(通过数据库查询session信息)总比做一次HMACSHA256计算的Token验证和解析要费时得多。


6.更优秀的JWT技术


JWT 是能够安全传输信息的一种方式。通过使用公钥/私钥对 JWT 进行签名认证。此外,由于签名是使用 head 和 payload 计算的,因此你还可以验证内容是否遭到篡改。


JWT不用像普通token一样对比验证存于服务器端的用户信息,而是通过加密和解密计算,服务器端只需要保留secret私钥


说到底,token和session只是服务器端保存的数据量减少,但服务器端依旧是要保存客户端的相关信息的,那么如果网站新开一个服务器,还得把原先服务器的用户数据给拷贝一份,当然这是没用数据库的情况下,那么有什么办法可以不拷贝一份吗,这就要用到JWT了


token相对于是服务器端也要保留给每一个用户的那个签名,每次用户的客户端发送信息过来,服务器端分离出签名,与存在服务器上的签名进行对比来确认身份,但是JWT就是只要是能通过服务器私钥解密的就认为是合法的客户端,所以不用保存每个用户的签名信息


目录
相关文章
|
11天前
|
JSON 安全 Go
Go语言中使用JWT鉴权、Token刷新完整示例,拿去直接用!
本文介绍了如何在 Go 语言中使用 Gin 框架实现 JWT 用户认证和安全保护。JWT(JSON Web Token)是一种轻量、高效的认证与授权解决方案,特别适合微服务架构。文章详细讲解了 JWT 的基本概念、结构以及如何在 Gin 中生成、解析和刷新 JWT。通过示例代码,展示了如何在实际项目中应用 JWT,确保用户身份验证和数据安全。完整代码可在 GitHub 仓库中查看。
54 1
|
19天前
|
存储 安全 搜索推荐
理解Session和Cookie:Java Web开发中的用户状态管理
理解Session和Cookie:Java Web开发中的用户状态管理
40 4
|
22天前
|
存储 缓存 网络协议
计算机网络常见面试题(二):浏览器中输入URL返回页面过程、HTTP协议特点,GET、POST的区别,Cookie与Session
计算机网络常见面试题(二):浏览器中输入URL返回页面过程、HTTP协议特点、状态码、报文格式,GET、POST的区别,DNS的解析过程、数字证书、Cookie与Session,对称加密和非对称加密
|
1月前
|
缓存 Java Spring
servlet和SpringBoot两种方式分别获取Cookie和Session方式比较(带源码) —— 图文并茂 两种方式获取Header
文章比较了在Servlet和Spring Boot中获取Cookie、Session和Header的方法,并提供了相应的代码实例,展示了两种方式在实际应用中的异同。
164 3
servlet和SpringBoot两种方式分别获取Cookie和Session方式比较(带源码) —— 图文并茂 两种方式获取Header
|
1月前
|
存储 安全 数据安全/隐私保护
Cookie 和 Session 的区别及使用 Session 进行身份验证的方法
【10月更文挑战第12天】总之,Cookie 和 Session 各有特点,在不同的场景中发挥着不同的作用。使用 Session 进行身份验证是常见的做法,通过合理的设计和管理,可以确保用户身份的安全和可靠验证。
21 1
|
2月前
|
存储 中间件 API
ThinkPHP 集成 jwt 技术 token 验证
本文介绍了在ThinkPHP框架中集成JWT技术进行token验证的流程,包括安装JWT扩展、创建Token服务类、编写中间件进行Token校验、配置路由中间件以及测试Token验证的步骤和代码示例。
ThinkPHP 集成 jwt 技术 token 验证
|
2月前
|
存储 缓存 数据处理
php学习笔记-php会话控制,cookie,session的使用,cookie自动登录和session 图书上传信息添加和修改例子-day07
本文介绍了PHP会话控制及Web常用的预定义变量,包括`$_REQUEST`、`$_SERVER`、`$_COOKIE`和`$_SESSION`的用法和示例。涵盖了cookie的创建、使用、删除以及session的工作原理和使用,并通过图书上传的例子演示了session在实际应用中的使用。
php学习笔记-php会话控制,cookie,session的使用,cookie自动登录和session 图书上传信息添加和修改例子-day07
|
2月前
|
JSON 安全 数据安全/隐私保护
从0到1搭建权限管理系统系列三 .net8 JWT创建Token并使用
【9月更文挑战第22天】在.NET 8中,从零开始搭建权限管理系统并使用JWT(JSON Web Tokens)创建Token是关键步骤。JWT是一种开放标准(RFC 7519),用于安全传输信息,由头部、载荷和签名三部分组成。首先需安装`Microsoft.AspNetCore.Authentication.JwtBearer`包,并在`Program.cs`中配置JWT服务。接着,创建一个静态方法`GenerateToken`生成包含用户名和角色的Token。最后,在控制器中使用`[Authorize]`属性验证和解析Token,从而实现身份验证和授权功能。
155 3
|
2月前
|
存储 安全 NoSQL
Cookie、Session、Token 解析
Cookie、Session、Token 解析
62 0
|
3月前
|
SQL Java 测试技术
在Spring boot中 使用JWT和过滤器实现登录认证
在Spring boot中 使用JWT和过滤器实现登录认证
249 0