仅供自学回顾使用,请支持javaGuide原版。
如果没有 Cookie 的话 Session 还能用吗?
一般是通过 Cookie 来保存 SessionID ,假如你使用了 Cookie 保存 SessionID 的方案的话, 如果客户端禁用了 Cookie,那么 Session 就无法正常工作。
但是,并不是没有 Cookie 之后就不能用 Session 了,比如你可以将 SessionID 放在请求的 url 里面https://javaguide.cn/?Session_id=xxx 。
这种方案的话可行,但是安全性和用户体验感降低。当然,为了安全你也可以对 SessionID 进行一次加密之后再传入后端。
为什么 Cookie 无法防止 CSRF 攻击,而 Token 可以?
CSRF(Cross Site Request Forgery)
一般被翻译为 跨站请求伪造。
那么什么是跨站请求伪造呢?其实就是用你的身份去发送一些对你不友好的请求。
javaGuide
原文提到原因如下:
上面也提到过,进行
Session
认证的时候,我们一般使用Cookie
来存储SessionId
,当我们登陆后,后端生成一个SessionId
放在Cookie
中返回给客户端,服务端通过Redis
或者其他存储工具记录保存着这个SessionId
。
客户端登录以后每次请求都会带上这个
SessionId
,服务端通过这个SessionId
来标示你这个人。如果别人通过Cookie
拿到了SessionId
后就可以代替你的身份访问系统了。
但是,我们使用
Token
的话就不会存在这个问题,在我们登录成功获得Token
之后,一般会选择存放在localStorage
(浏览器本地存储)中。然后我们在前端通过某些方式会给每个发到后端的请求加上这个Token
,这样就不会出现CSRF
漏洞的问题。因为,即使你点击了非法链接发送了请求到服务端,这个非法请求是不会携带Token
的,所以这个请求将是非法的。
简化解释来讲就是,使用Cookie
存储SessionId
时,浏览器会自动发送Cookie
,攻击者可利用这一点,通过诱导用户点击恶意链接,冒用用户身份发起请求(CSRF攻击
)。
而Token
存储在localStorage中,不会自动发送。每个请求需手动添加Token
,恶意链接无法获取和发送Token
,因此无法冒用用户身份,有效防止CSRF攻击
。

我本人更喜欢以下的解释,Cookie
和token
的区别会更清楚一点:
Cookie
无法防止CSRF
攻击的原因:
- 自动发送:当用户访问某个网站时,浏览器会自动发送与该网站相关的
Cookie
。这意味着即使请求是由攻击者构造的,只要用户已经登录过目标网站,Cookie
就会自动包含在请求中,从而被攻击者利用。 - 通常缺乏请求特异性:
Cookie
通常是用于身份认证的,它们一般不特定于某个请求或会话(除非特意设置了Cookie
的path
属性)。因此它一般会在所有符合条件的请求中被发送,这为CSRF
攻击提供了可乘之机。 - 通常在客户端长期存储:
Cookie
一般会在客户端存储较长时间段。在该时间段内,用户登录已登录的网站,Cookie
不变。
Token
可以防止CSRF
攻击的原因:
- 需要主动提交:
Token
需要开发者显式地在请求中提交(譬如由前端注入),而不是由浏览器自动发送。这增加了攻击者构造有效请求的难度,因为它们需要知道Token
的值并将其包含在请求中。 - 请求特异性:
Token
通常是针对每个请求或会话生成的,其可以和特定请求参数或HTTP
头结合,从而具有唯一性。这意味着即使攻击者知道了某个Token
,它也只能用于特定的请求,而不能用于其他请求。 - 通常不在客户端长期存储:
Token
通常不会在客户端长期存储。即使登陆过相同网站,可能第二次登录时服务器就生成了新的Token
交由客户端。
需要注意的是:不论是 Cookie
还是 Token
都无法避免 跨站脚本攻击(Cross Site Scripting)XSS
。
跨站脚本攻击(Cross Site Scripting
)缩写为 CSS
但这会与层叠样式表(Cascading Style Sheets,CSS)
的缩写混淆。因此,有人将跨站脚本攻击缩写为 XSS
。
XSS
中攻击者会用各种方式将恶意代码注入到其他用户的页面中。就可以通过脚本盗用信息比如 Cookie