通过本文将了解什么是网页Cookie和token以及他们的用途;以及最常见的网页Cookie和tokens类型。
什么是cookies?
Cookies是网站(网络服务器)访问时创建并存储在设备中的小型文本文件。几乎每一个你访问的网站都会有一个cookie通知栏。cookie的用途取决于cookie的类型以及网站希望cookie执行的任务。比如一个网上购物的商店可以使用cookie来跟踪用户在其网站上的活动,最后访问的页面,选择的语言,浏览的商品以及放入购物车的商品。当用户离开网站但后来返回时,网站可以读取cookie。
为什么需要cookie
因为HTTP是一种无状态协议。HTTP不记得客户端的会话信息,因此客户端负责存储这些信息————使用cookie。某些网站,无状态行为可能没问题,也许网站上没有需要用户在会话期间保留的元素或用户操作。但对于大多数交互式网站,cookies是必要且必不可少的。
当客户端从网络服务器请求网站时,网络服务器响应“200 OK”并使用Set-Cookie头向客户端发送cookie。cookie包含会话ID,通常还包含其他属性。Web服务器也在服务端跟踪其分发给客户端的绘画ID。
Cookie主要用于:
- HTTP会话管理
- 个性化
- 跟踪
浏览器会将Cookie存储在用户的计算机上。具体来说,它存储在硬盘的临时目录中。存储cookie的具体位置和方法取决于浏览器和操作系统。一般,可以通过浏览器界面的设置来管理cookies,但不同操作系统和浏览器文件路径可以在互联网上找到。如MicroSoft Edge将cookie存储在以下路径:C:\Users\[username]\AppData\Local\Microsoft\Edge\User Data\Default\Cookies-MSEDGEPROFILE.DEFAULT其中,[username]是用户的登录名。
Cookie属性
Cookie属性具有一些非常重要的属性,因为他们定义了cookie的工作方式。以下是cookie可以具有的一些属性列表:
- Session ID: 是一个用于识别和匹配客户端和网络服务器之间唯一的随机字符串
- Expires: 定义了cookie的过期日期
- Domain: 制定了该Cookie可用的域名或多个域名
- Path: 指定了可用于访问的资源或者路径
- HttpOnly: 启用时将防止客户端API(如js)访问cookie,这有助于减轻跨站脚本(Xss)攻击的风险
- Secure: 启用时将只允许通过HTTPS发送cookie,而禁止使用HTTP等未加密链接,这使得cookie更不容易受到Cookie窃取的攻击
- Session:定义cookie是一个临时的cookie,当浏览器关闭时过期
- SameSite:可以有strict,lax,或none值
- strict=浏览器仅将cookie发送到与来源相同的目标域
- Lax-浏览器将cookie发送到不同于来源的目标域,但仅限于安全请求(如Get)且不是第三方cookie
- None=允许第三方cookie(跨站点cookie)
Cookies的类型
- 必需Cookies
必需cookie对于网站正常运行是必要的,通常使用户浏览体验更方便
- 会话cookie(非持久cookie,内存cookie,临时cookie)
- 第一方cookies
- 认证cookies
- 用户中心安全cookies
- 用户输入cookie 会话cookie是临时cookie文件,当用户关闭浏览器或其会话变为非活动状态时会被删除(如果用户注销,会话将结束)他们是单次会话。当用户重新启动并返回创建cookie的网站时,网站将无法识别用户,因为浏览器中没有cookie可供读取。如果网站需要登录,用户将需要重新登录。登录后将生成一个新的会话cookie,它将存储用户的浏览信息并在用户离开网站关闭浏览器之前保持活动状态。由于会话cookie具有其独特的ID,它还可以用于跟踪网站访问者数量。比如,你如果每天多次访问旅行社的网站,会话cookie ID将向该网站透露您是一个独特的访客。 第一方cookie(又称持久性cookie、永久cookie、存储cookie)会一直存于浏览器中,直到用户手动删除他们,或者浏览器根据持久cookie文件中的持续时间将其删除。第一方cookie最常见的作用是让用户保持登录状态,从而避免每次访问重新输入凭据。 认证cookie是会话cookie的一种变体。他们将在成功登录后识别用户并在用户导航到授权内容的网站时携带该认证信息。
- 非必要cookie
- 分析和定制cookies
- 广告cookies
- 第三方cookies
- Supercookies:超级cookie在技术上并不是真正的cookies,在某些情况下不会存储在用户的设备上。普通cookie最多容纳4kb的数据,而Supercookies可以容纳100KB
什么是tokens
Tokens是用于信息交换的自包含紧凑型JSON对象。典型的token是客户端与另一个服务之间使用的JSON Web Token(JWT);与存储用户在网络会话中的活动信息的cookies不同,tokens是在软件之间传输信息。tokens作为协议的一部分,并非所有令牌都属于同一协议。
我将在这里简要解释一下OAuth2.0和OpenID Connect(OIDC),因为他们被Microsoft identify Platform使用。
OAuth 是Open Authorization的缩写,是一种用于处理程序或者网站代表用户访问资源的授权流程的标准。即OAuth主要是用于web平台授权的协议。OAuth使用访问token,但通常不限于JSON Web Tokens。Microsoft identify Platform中的OAuth协议使用格式化的JWTs的访问token。OAuth2.0授权流程有多种不同的类型。
OpenID Connect扩展了OAuth 2.0授权协议,使其也用作认证协议,使用ID token。OpenID Connect登录流程用于获取发送给验证用户身份的应用程序的ID令牌。
Tokens解决的问题
一个传统的认证和授权场景(其中不存在tokens):用户首先登录,web服务器通过其数据库中的输入凭证来认证用户,一旦凭据匹配,服务器就会发出一个唯一会话标识符并将其发送给客户端。用户会将会话ID保存在其设备上。客户端每次向服务器发送请求时,都会在cookies或http请求头中发送会话ID,服务器需要再次从数据库中查找会话ID,以识别用户并检查其授权级别。 上述场景的问题在于,对于每次客户端向服务器发送请求时,服务器都需要向数据库发送一次请求,这使得程序的使用速度变慢。
而使用tokens的场景通过发出包含用户信息和验证tokens内容真实性的签名的JWT解决了随后数据库查找的问题。JWT发送到客户端,客户端再次存储它,每次客户端向服务器发送请求时,客户端都会包含JWT。服务器只需要验证token的签名以及确保其真实性,当验证通过时,服务器可以从token中提取身份和授权详细信息,而无需数据库查找。
Tokens的类型
常见的tokens类型有:
- ID token:是通过OpenID Connect(OIDC)登录流程获取的,这是一个去中心化认证的开放标准。ID tokens必须采用JSON Web Token格式。他们由授权服务器(Microsoft Entra ID)向客户端应用程序签发。ID token包含用户和安全主体的声明,并可以包含关于多重认证(MFA)状态的声明。比如:客户端应用程序可以使用ID tokens中的信息和声明验证用户的身份。默认情况下,Microsoft identify Platform中的ID tokens有效期为一小时。 ID tokens不用于调用受保护的API。
- 访问 token:是授权服务器签署的短期JWT token,它使客户端能够安全地调用受保护的API。访问 tokens不需要使用JSON Web token格式,但是在Microsoft identify Platform中采用JWT的格式。客户端的每个http 请求都包含访问token。通常是在HTTP请求的Authorization头部使用“Bearer”模式来实现这一点。这样可以避免服务器在每次请求时都需要对用户进行身份验证。客户端将访问 token存储在cookies或者本地存储中。与ID tokens类似,访问tokens也有两个版本,每个版本由不同的端点。访问tokens是为了在服务器端使用。客户端不需要也不应使用访问token的内容。
- 刷新 token:刷新token通常与访问token一起获取。它用于在之前的访问token过期时获取新的访问tokens和新的刷新token。在Microsoft identify Platform中,刷新tokens是加密的,不能被其他人读取。客户端将访问 token存储在cookies或者本地存储中。刷新token的有效期为90天,单页应用程序是例外,其有效期为24小时。
- 持票人 token:是指任何持有该token的人都可以使用的tokens。token持有者不必证明持有加密密钥。可以将其视为酒店的房卡。如果你丢失了房卡,其他人捡到后都可以使用它进入房间,而不需要证明他们是房间的合法所有者
JSON Web Token(JWT)
JWT是用于在两方之间安全传输数据的标准化对象。为了确保在传输过程中JWT的内容未被更改或篡改,JWT使用加密密钥进行签名。即JWTs是签名的,不是加密的。签名验证数据发送者,而加密是将数据转换成只有授权接收者才能阅读的秘闻。如果在传输过程中签名的token内容被更改,公钥(用于验证token签名的私钥对)将无法再验证签名。强烈建议JWTs一起使用HTTPS等协议,以保护传输过程中的token内容的机密性。 JSON Web Token实际上就是一个形同lll.zzz.xxx的字符串,由三个部分组成,分别进行base64编码后以点‘.’进行分割,这三部分如下:
- 头部:它通常包含两个部分,分别描述令牌的类型和签名算法
{
"alg":"HS256",
''type:'JWT'
}
- 有效负载:负载是包含所有实际信息的部分
- 签名:头部和负载都经过Base64Url编码,为了签名token,需要使用编码后的头和负载,以及密钥和签名算法来完成。
JWT的安全问题
-
大小限制和存储 一些复杂的应用程序需要在tokens中存储大量信息。当tokens存储在cookies中时,这会增加每个请求的开销,甚至超过cookies允许的大小(4KB)。当这种情况出现时,常见的解决方案是将JWT存储在本地存储中,这有其自身的安全问题,主要是本地存储的数据对页面内的任何脚本都是可以访问的。这可能导致跨站脚本攻击能够访问token。 一般来说。cookies旨在由服务器读取,而localStorage只能由浏览器读取。这意味着cookies有限制较小的数据量,而localStorage没有这种限制。当token存储在本地时,浏览器使用js访问它。这是token存储在本地设备容易被跨站脚本攻击的根本原因,因为攻击者会将恶意的JS注入网页并窃取访问token。本地存储不提供任何安全措施,而cookie具有secure属性可以保护cookies免受XSS攻击。
-
失效: token是自包含的。没有中央机构跟踪和管理tokens。这在尝试使token失效时成为一个挑战。默认情况下,访问token的有效期为1个小时,有效期详细信息包含在token中
-
未加密:请记住,token是签名的,但不是加密的。因此,如果未通过HTTPS充分保护,token内容可能会暴露给未经授权的一方