CSRF,这个CORS是不一样的,长的比较像,也比较容易混。CSRF往往和系统的安全扯上联系,也是等保测试中比较重要的测试内容,它也是和Cookie有关的,大体的流程是这样的,
用户登录了A网站,并没有退出;
此时,用户又访问了B网站;
在B网站有个隐藏的请求,请求了A网站的一个重要的接口,比如:转账、支付等。
在请求A网站的同时,带上了A网站的Cookie,所以一些危险的操作就成功了。
关于CSRF的攻防,在我前面的文章《CSRF的原理与防御 | 你想不想来一次CSRF攻击?》中有详细的介绍。总之,使用Cookie实现登录是需要重点防范一下CSRF攻击的。
JWT方式近年来,由于手机端的兴起,前后端分离开发方式的流行,JWT这种登录的实现方式悄然兴起,那么什么是JWT呢?JWT是英文JSON Web Token的缩写,它由3部分组成,
header,一般情况下存储两个信息,1类型,一般都是JWT;2加密算法,比如:HMAC、RSA等;
payload,这里就存储登录的相关信息了,比如:登录状态、用户id、过期时间等。
signature,签名,这个是将header、payload和密钥的信息做一次加密,后台在接收到JWT的时候,一定要验签,谨防JWT的伪造。
下面咱们看看JWT的登录实现,
我们看到整体的流程和Cookie的实现方式是一样的,只不过是没有用到Cookie、Session。那么它与Cookie-Session的区别是什么呢?
登录状态、用户id并没有存储到session,而是存在JWT的payload里,返回给了前端。
在前端JWT不会自动存储到Cookie中,前端开发人员要处理JWT的存储问题,比如LocalStorage
再次发起请求,JWT不会自动放到请求头中,需前端同学手动设置
后端从请求头中取出JWT,验签通过后,拿到登录状态、用户id,不是从session中取
相比Cookie的方式,JWT的方式需要更多的开发工作量。那么其他的问题存在吗?我们一个一个看。
分布式会话我们后台部署多个服务,会有分布式会话的问题吗?
无论请求被分配到哪一个后台服务中,登录状态和用户id都是从JWT中取出来的,不会出现分布式会话的问题。我们在后台部署集群的时候,根本不用care这个问题。
CORSCookie的跨域受到同源策略的保护,不经过特殊的设置,是不能够跨域的。那么JWT呢?JWT是前端同学手动在请求头中设置的,如果向其他的域发送请求要注意,稍不注意,在请求的时候,调用了封装的公共方法,就会把JWT发送给其他域的后台,前端的小伙伴要打起精神啊。
CSRFCookie的方式,B访问A网站,会把A的Cookie带上,从而造成了安全隐患。那么JWT呢?JWT在前端存储在A网站的域下,B在访问A网站时,是拿不到A网站的JWT的,那么也不可能在请求头中设置JWT,A网站的后台拿不到JWT,也不会做其他操作。所以,JWT可以很好的防止CSRF攻击。
总结通过前面我们对Cookie和JWT的分析,可以总结成如下的表格,
Cookie-Session JWT工作量 浏览器和容器天然支持 需要额外开发,有一定工作量
分布式会话 需要借助中间件 无需关心,登录信息从JWT解出
CORS 不支持跨域、需特殊设置 开发人员设置请求头,可以跨域
CSRF 需特殊防范 无需防范,第三方拿不到JWT
好了,Cookie和JWT的特点都总结出来了,大家在实现登录的时候,就各取所需吧。结合自己的项目,选择适合自己项目的实现方式吧。