Cookie,Session,JWT

Cookie,Session,JWT,第1张

Cookie,Session,JWT HTTP协议

HTTP协议是一种无状态的协议。

早期WEB为了推广,需要一种可以快速共享资源的网络传输协议,这种协议旨在从服务器快速推送资源给任意一个客户端,而不在乎访问者是谁,后面就发明了HTTP协议。HTTP协议的无状态性是指HTTP协议无法记录传输过程中访问者是谁。

但是,随着WEB的发展,各种致力于为私人用户提供特定服务的服务器开始出现,比如电商服务器,用户需要经过电商服务器的身份认证才能继续使用服务器的其他功能。而HTTP协议本身是无状态的,即HTTP协议本身无法记录访问者信息。

身份认证解决方案

为了解决HTTP协议的无状态性,出现了三种解决方案cookie,Session,JWT。而这三种解决方案特点各不相同。

cookie

cookie是由服务器生成

当客户端访问服务器的特定API时(如登录),服务器(程序员编写的某段代码)会给客户端生成一个身份认证标识(如:某字符串),在响应客户端时,会将这个身份认证标识放到HTTP响应消息头的set-cookie属性中,以键值对的形式存储。

cookie需要保存在客户端中

这里的客户端可以是常规的浏览器,也可以是接口测试工具,如Postman,JMeter,Burpsuite等,其中浏览器在得到服务器响应的set-cookie后,会将cookie信息保存到本地的浏览器缓存(一个文件)中,postman也可以自动保存服务器响应的set-cookie信息,但是JMeter,Burpsuite不会,它们需要人为手动保存。

客户端请求服务器时可以(不是必须)携带cookie信息

客户端中,如浏览器,Postman可以自动检查自己保存的cookie,找到其中有效的,存活的,将其加入到HTTP请求消息头的cookie属性中,以键值对的形式保存,服务器端收到客户端的请求消息后需要人为取出请求消息头的cookie信息加以判断使用

cookie的生命周期由服务器设置

在服务器生成cookie后,需要设置cookie保存的具体信息,以及有效期。这里的有效期就是cookie的生命周期。一般来说,cookie有效期较长,有一周或两周左右。

服务器的自动身份认证cookie实现

1、当用户首次登录某网站时,网站服务器收到用户登录请求,验证用户身份信息后,程序员会编写一端代码:

生成一个关联用户身份信息的字符串(如包含用户名或用户id的字符串),将其加入到一个cookie对象中,设置cookie有效期为一周。

并在登录成功的HTTP响应消息的消息头中加入set-cookie属性,其值为上面的cookie对象。

2、浏览器收到服务器响应后,会自动将HTTP响应消息头中的set-cookie信息保存到浏览器缓存文件中。

3、当用户关闭浏览器后,再次打开上次网站时,浏览器会找到缓存文件中的有效的cookie,并加入到这次HTTP请求的消息头中的cookie属性中,发送到服务器。

4、服务器收到请求后,需要程序员编写代码来获取HTTP请求头中的cookie信息,第一步验证cookie有效期,第二步获取cookie保存的用户身份信息,获取到身份信息后,加以验证,验证通过后,则可以直接使用该身份信息,并跳过登录验证流程,直接跳过登录验证后的资源响应给客户端。

5、客户端浏览器收到响应后,发现无需登录,网站已经是自己身份的登录状态了。

关于浏览器端如何保存cookie

浏览器会自动将服务器的HTTP响应消息头中的set-cookie信息存储到本地的一个缓存文件中,存储形式如下

常说的清除浏览器缓存是什么概念,是否等价于清除cookie?

浏览器缓存是一种减轻服务器压力的解决方案,那么服务器有什么压力呢?

当我们打开某个网站时,呈现在浏览器上的网页上的所有资源都是服务器1kb,1kb的发送过来,如果我们不停地请求网站地同一资源,服务器需要不停地无意义地响应。这就是服务器的无意义的压力。为了解决用户这种无意义 *** 作带给服务器的压力,浏览器会缓存一些用户经常请求的服务器资源在本地,并记录资源对应的URL信息,当用户再次请求相同URL时,浏览器会自动将缓存中的资源响应给用户,而不是去发送请求到服务器重新获取。

这就是浏览器缓存的作用。

那么cookie是什么呢?cookie通常用来保存用户的一些身份认证标识,浏览器可以自动地保存cookie到缓存中,也会自动地仓缓存中获取cookie,从而避免了用户在访问服务器资源时被反复要求身份验证的情况。

也就是说cookie的作用和浏览器缓存资源的作用是不同的,浏览器缓存资源是为了帮助服务器减轻压力,浏览器缓存cookie是为了帮助用户避免反复登录验证。只是cookie被浏览器放在了缓存中而已。

浏览器清除了缓存中cookie文件后,再次访问对应网站还是登录中状态吗?

浏览器每次访问网站都会去缓存中找到有效的cookie信息并加入到请求消息头cookie属性中,如果浏览器在缓存中没有找到有效的cookie信息,那么这次的请求消息头就没有cookie属性,那么服务器也无法获得cookie信息来验证用户身份,则只能让用户再次登录了。

cookie可以被盗用吗?

所谓盗用,也就是说非本人使用,那么该如何获取到他人的cookie呢?市面上有不少方法,这里就不作深入了,我们只需要知道cookie是可以被盗用的,而且方式还不少,成本也很低。

其他人可以使用我自己的cookie免登录吗?

HTTP协议是无状态的,所以服务器无法从HTTP协议知道发起者是谁,如果有cookie认证,则可以通过对应的cookie信息知道发起者是谁,但是cookie就像一个古代虎符一样,谁拿到谁就可以调动军队,军队是不管谁持有虎符的。

如果有人在我清除浏览器缓存中的cookie文件之前拿到cookie,此时我本地没有cookie了,我登录需要认证了有了新的cookie,那么盗取我老cookie的人还可以免登录吗?

等待验证

cookie安全吗?

cookie会被保存在浏览器的缓存中,即客户端主机上,而普通用户的主机的防护功能一般而言都很弱(cookie被盗取风险大),更不用说用户自身的防护意识了。可能有的人在网吧上完网都没有清除浏览器cookie的习惯,网吧浏览器如果没有设置关闭浏览器自动清除cookie的话,后面一个上机的人就可以轻松免登录你的账户了(cookie生命周期长)。

所以cookie不安全,原因是:

1、保存在客户端主机上

2、生命周期较长

3、容易被伪造,由于cookie是保存在客户端的,而且cookie里面保存的是实实在在的用户身份认证信息,所以黑客只需要获得足够多的样本,经过对比破译,就可以解析出用户的身份信息,并获得加密方法,就可以实现随意伪造。

Session

Session是由服务器生成的

用户在浏览器登录某网站后,网站服务器(程序员编写的某段代码)会将用户的身份认证信息保存到一个Session对象中,并将Session对象持久化到服务器的某个文件或数据库中。而为了方便找到这个Session对象的位置,会同时生成一个位置信息SESSION_ID(通常是保存session对象的文件名或数据库对应数据的唯一主键id)。持久化完成后,服务器会将SESSION_ID信息放到HTTP响应头的set-cookie中。

SEESION_ID是Session吗?

我们需要知道用户的身份认证信息保存在了Session中,Session被保存到了服务器的文件或数据库中。那么服务器如何找到茫茫文件或者茫茫数据中的Session呢?此时就诞生了SESSION_ID。说白了,SESSION_ID就是一把钥匙,Session才是宝库。

Session保存在服务器端

通过上面,我们可以知道Session保存在服务器的文件或数据库中

SEESION_ID保存在哪里?

我们知道服务器会生成SEESION_ID,并将它放到HTTP响应消息头的set-cookie中给客户端。那么客户端会将它保存在本地缓存的cookie文件中吗?

答案是不会。

区别于普通的cookie信息,SESSION_ID不会保存在客户端本地缓存的cookie文件(硬盘)上,而是保存在浏览器的内存(内存条)上。

SEESION_ID的生命周期

我们知道硬盘是持久保存数据的,而内存是临时保存数据的,当浏览器被关闭, *** 作系统就会收回分配给它的内存,这样SESSION_ID就没了。

所以SEESION_ID的生命周期就是从服务器产生它开始,到客户端浏览器关闭为止。

session的生命周期

session是保存在服务器的,程序员创建session对象时,都会指定其有效期,一般是半小时或24min,即session的有效期就是他的生命周期。

SESSION_ID如何实现免登录

浏览器在访问网站时,会自动将浏览器内存中SESSION_ID加入到HTTP请求头中的cookie属性中。服务器收到客户端请求,(程序员编写的某段代码)就会取出请求头中的SESSION_ID,并去数据库或文件中查找是否存在对应用户身份认证信息,如果存在,就会免登录。

session会被盗取吗

可能性不大,session是保存在服务器中的,而相较于普通用户的客户端主机,服务器的防护能力和防护意识都是碾压级的,一般黑客都无法盗取。但是如果服务器保护机制出现漏洞,还是有可能被盗取的。

SESSION_ID会被盗取吗
SESSION_ID保存在浏览器内存中,难度比从硬盘盗取大的多。

但是如果人为记录SESSION_ID到硬盘那就没办法了。

另外拦截发送到服务器的请求,也能盗取到SESSION_ID.

被盗取的SESSION_ID可以帮助非本人免登录吗

可以,因为HTTP协议是无状态的,SESSION_ID称为身份认证的一种途径,谁得到SESSION_ID,谁就是本人。和虎符一样,谁得虎符,谁就能号令军队。

session机制和cookie机制谁更安全

1、具体身份认证信息保存位置,session在服务器,cookie在客户端,session更安全

2、有效期,session有效期一般在24min或0.5h,而cookie有效期一般在一周左右,session更安全

3、身份伪造的难度,cookie直接将身份信息保存在了客户端,就算身份信息被加密保存了,黑客只需要难道足够到的样本数据,总能破译。

        而session将用户身份信息保存在了服务器,黑客首先进入服务器就是一个难关,更不要说后面的获取session,破解session中的用户身份了,而保存在客户端的SESSION_ID只是一串和用户信息无关的地址,黑客破解它得不到任何东西。

session机制的弊端

可以说session无论是在哪个方面都已经很安全了,那么它有什么弊端呢?

那就是保存session的代价太大。

大型网站的用户都是上亿的,如淘宝和微信,那么上亿用户的session信息保存是一个问题。有人说不就是保存在服务器的文件或者数据库吗?

那么如果保存session的文件或数据库故障了呢?那么所有用户都无法正常使用网站了,每次请求需要身份认证的接口,都会查询session,但是session的载体有坏了,所以只能要求用户重新登录,但是重新登录生成的session又无法存储,因为载体坏了,所以访问新的接口又要重新登录。

所以,有了集群载体,即载体A故障了,立马就去载体B查询。那么一个session就会被复制多个,那么上亿条session被复制的代价可想而知。

总之一句话,session很安全,但是很费服务器硬盘。

而cookie虽然不安全,但是却用的是客户端的硬盘,减轻了服务器的压力。

JWT

JWT是啥

JWT全称 json web token,是一种新的HTTP协议身份认证解决方案。

JWT解决了什么问题

JWT解决了session的弊端,即服务器不需要保存用户身份认证信息。

JWT核心原理

session对于服务器的硬盘消耗让大型企业望而却步,但是cookie的安全性又企业头疼不已。

如果有一种方案可以有session的安全性,有cookie的服务器硬盘友好性,那么是极好的。

JWT就符合该要求。

JWT由服务器生成,由三部分组成(注意.也算)

header.payload.signature

关于这三部分的介绍:JSON Web Tokens - jwt.io

header中存储的是第三部分signature的签名加密算法alg,和字符串类型是JWT

payload中包含私有的身份认证信息,服务器一般在用户登录后,将其身份认证信息放到payload中

这里,header和payload都是使用base64简单编码的,可以很容易的被解码咋展示明文,所以在payload中,我们不能放入用户敏感信息,比如密码和手机号或者家庭住址之类的

第三部分signarture,是帮助服务器验证用户身份的。

这里有几个问题:

为什么服务器生成的JWT要包含header和payload,而且还只使用base64简单编码?这不是暴露了用户身份认证信息了吗?

上面的疑问可以转变为:JWT可不可以只包含signature?

那么我们需要知道signature是干什么的,以及如何产生的?

signarture是服务器端根据header和payload中信息生成一个加密信息,具体加密逻辑是:

某种加密算法(base64UrlEncode(header) + "." +
  base64UrlEncode(payload),加密算法所需密钥)

这里的加密算法可以是HS,RS,ES,PS算法

所以signature是一个加密信息,而且只有掌握密钥的人才能使用它

所以只要密钥不泄露,黑客很难破译。

对于使用JWT进行身份认证的服务器来说,服务器将生成的JWT响应给客户端,客户端后续 *** 作需要将JWT再发送给服务器做身份认证。

如果客户端的JWT被篡改,那么你觉得哪些部分可以被篡改?

答案是:payload

因为header是存储signature加密方式的,这个不能改,改了服务器端肯定验证不过。

signature是保存(header+payload)合并后的加密信息的,由于不知道密钥,所以无法将其解密,也就无法篡改其中的明文信息了,如果强行改密文的话,等于自杀。

所以只有可以解码为明文的payload可以篡改,假设我将payload篡改为另一个人的身份认证信息。然后发送给服务器。

服务器会按部就班的获取出header和payload信息,并且按照如下公式:

某种加密算法(base64UrlEncode(header) + "." + base64UrlEncode(payload),加密算法所需密钥)

得到一个新的signature。对比客户端发送来的老signature,如果两者不同,则说明JWT被篡改,非正常行为。

这里可以发现服务器验证用户身份的方式就是

先自己根据header和payload加密得到一个只有自己能验证的signature,然后将三者组装在一起发送给客户端。

客户端下次请求再带着这个三个东西到服务器,服务器再次将客户端发来的header和payload用相同的方式加密得到一个新的signature,对比客户端发来的signature,如果相同就说明验证成功,否则验证失败。

所以服务器发送的JWT中的header和payload只是辅助signature用的,且是必要的。

JWT保存在哪里

我们知道cookie保存在浏览器的缓存的cookie文件中,Session保存在服务器的文件或数据库中,那么JWT保存在哪里呢?

JWT保存在客户端中,这一点是肯定的,因为JWT就是为了解决Session弊端而产生的。

那么JWT保存在客户端哪里呢?

答案哪里都可以,既可以保存在cookie中,也可以保存在浏览器的LocalStorage中。

但是需要注意的是:

保存在cookie中的信息容易被CSRF(跨站请求伪造),关于CSRF的简单介绍

 a用户访问A网站,登录成功,并在本地生成了身份认证cookie,且不会短期失效。

a用户之后访问B网站,B网站上有一个恶意链接引诱a去点击,这个恶意链接是用户在A网站上执行转账的一个接口。

由于B网站无法获取到a的身份信息,所以无法以a的身份去登录A网站转账。

但是当a用户浏览器有了A网站的身份认证cookie,那么B网站就可以伪造一个转账链接去引诱a用户去点,只要a用户一点,浏览器就会自动携带A网站的cookie信息,免登录,直接执行转账接口。

保存在LocalStorage中的容易被XSS(跨站脚本攻击),关于XSS的简单介绍

在开发网页时,动态生成标签并拼接到网页中是一种常用的实现动态网页的技术。

但是动态生成的标签有一个安全问题:

动态生成的标签中的内容来源不确定,可能来自于服务器,也可能来自于用户网页输入的内容,如果来自于用户输入,那就有可能被XSS风险,如用户输入,如果前端没有加以校验就直接拼接的话,就被注入了恶意脚本。如果脚本写的在深入一点

服务器如何将JWT发送给客户端

cookie和SESSION_ID都是放在HTTP响应头的set-cookie中的,那么JWT放在哪呢?

答案是哪都可以,可以放在HTTP响应头中,也可以放在HTTP响应体中.

如果放在响应消息体中,记得自己取出来保存就行。

客户端如何将JWT发送给服务器

1、放在req.header.cookie中

2、放在req.header.authorization中

3、放在req.bdoy中

 

1可以浏览器自动携带,不需要额外动作。缺点:不能跨域。

2可以跨域,但是需要自己塞进去。

3可以快于,但是需要自己塞进去。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/4666286.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-06
下一篇 2022-11-06

发表评论

登录后才能评论

评论列表(0条)

保存