cookie session token

732 阅读13分钟

Cookie | Session | Token概念以及区别:

前提一定要记住:http协议是一种无状态的协议(客户端和服务端互相不认识)

当年在B站注册一个账号的时候,登录过一次之后,再次访问,你会发现不用再次输入密码和用户名来进行登录操作,这是为什么呢?

众所周知,HTTP是无状态的,你这次访问了服务器,关闭浏览器,再次打开浏览器访问服务器,服务器是没有意识到又是你来访问它的。

“不知道是我访问?怎么保持登录状态呢?”这里有好几种技术可以实现,其中最核心的概念就是存储,我们在b站注册了以后,我们的用户名和密码会被b站保存到数据库,也就是说,下次登录的时候b站就会把输入的用户名和密码与数据库中的数据相比对,如果存在对应的数据,则允许登录。

重点来了,如果b站不想让已经登录过的人重新输入账号密码呢?假设一天后要重新登录账号密码,就得使用到存储了,最简单的就是设置用户可以选择记住用户名和密码,让浏览器记住用户名和密码,但是这又有潜在的风险,如果你的电脑被黑了,那么你的浏览器中的数据也有风险。就算浏览器能够保证你的账号密码不被破解,我们还得解决http无状态的问题,因为即使我们不输入用户名和密码,浏览器还是得想办法把我们的用户名和密码加入到请求中,这样才能保证登录。

那么这里就是我们要讲的每次HTTP请求可以自动带数据给服务器的技术:Cookie。

Cookie的基本流程是这样的:

1.浏览器发起HTTP请求:

image-20220709093055171

2.服务器会进行Cookie设置,也就是Set-Cookie,Cookie中有 name :value 两个属性,服务器会把 属性里面的内容填充完整,Cookie发给浏览器后,浏览器会保存起来,这样浏览器以后发送的每一个请求都会自动附上这个Cookie,说白了Cookie就是一种存储在浏览器的数据而已:

image-20220709093519387

Cookie的优点:

  • 保存到客户端,容易被篡改(删除、禁用)
  • 保存的数据量有限的
  • 简单易懂好用

Cookie的缺点:

  1. 保存在客户端,容易被篡改。
  2. 大小受限,本身最大4kb

cookie和session区别

  • cookie是保存在客户端的
  • cookie有大小限制
  • session是保存在服务器端
  • session更加安全
  • session会比较占用服务器性能,当访问增多时应用cookie

Session概念:

而且实际上我们打开浏览器是可以看到保存了哪些Cookie的,也就是说把用户名和密码放在Cookie保存是很不安全的,只要电脑被黑,在Cookie中的重要information就会泄露,于是后面就有了一个新的概念:Session(会话)

既然浏览器和服务器是在进行会话的,浏览器访问服务器就是会话的开始,但比较模糊的是会话结束的时间,因为你关掉了网页,也有可能只是按错了而已,因此不同的网站对每个用户的会话都设定了时间以及唯一ID,这里的ID就是通常所说的Session ID,这里的时间就是指会话结束的时间, 因为是服务器自己定义的东东,所以一般会存储在在服务器的数据库中

image-20220709094446835

有了用户名为什么还要搞个Seesion ID?我们回顾一下访问B站的过程:

1.我们使用 用户名以及密码 访问B站服务器:

image-20220709094701797

2.B站服务器核对一下,确认用户名和密码是正确的,身份认证成功,于是就在服务器这边创建一个Session ID和会话结束时间

image-20220709094940912

3.这个Seesion ID通常是一串没有规律的字符串,当然还会创建其他参数,我们先看重点,服务器就需要把Session ID和会话时间发送给浏览器,这里就用到了Cookie(划重点),设置Cookie,并且把Seesion ID加入到Cookie中,再把会话结束时间对应设置为这个Cookie的有效期浏览器拿到Cookie后进行保存,注意了,这个时候浏览器没有保存用户名和密码,保存的Session ID也是没有规律的字符串,这个Cookie里面也就只有这个Session ID最重要,没有别的重要信息

image-20220709095526903

4.这个时候大家会疑惑,如果黑客入侵拿到Session ID怎么办?不能说这个黑客拿到Session ID没有意义,只是意义不大了,首先这个Session ID是没有规律的字符串,即使黑客有着柯南的智商,也不能根据Session ID推断出用户的密码,其次服务器在发送Cookie之前是会对这个含有Session ID的Cookie进行签名,换句话说,如果黑客修改了Session ID,Session ID就会变成服务器识别不了的字符串,所以浏览器保存Cookie后,利用Cookie的核心特点:【每个请求都会自动发送Cookie到相应的服务器里】,换句话说,浏览器的下次访问、下下次访问等等都会自动发送这个Session ID给服务器,直到Cookie的有效期失效之后,浏览器一般会自行删除这个Cookie,这就是会话结束了,那么在会话结束后,用户就得重新输入用户名和密码了:

image-20220709100423000

总之,整个过程就是:

登录页面---》输入账号密码---》浏览器发http请求访问服务器,http的body中包含账户密码---》服务器接收到http请求,将传过来的账号密码和数据库中的数据比对,如果是注册过的用户,则响应请求,返回对应的页面数据,还会返回一个Cookie,其中包含了Session(本质是Session ID,因为session的有效期设置成和Cookie同步了),服务器也会在自己这边创建一个Session用于记录与后续匹配---》浏览器得到响应的数据后,显示页面,并且将Cookie变成本地文件保存在浏览器中----》下次再登录的时候(或者重新刷新页面),发过去的请求中附带Cookie,而Cookie中又有Session ID和服务器那边的Seesion匹配,匹配成功,服务器直接给浏览器返回页面数据,也就保持了用户的登录状态

Token的概念:

1.随着互联网的发展,用户群体变得越来越大,如果服务器依旧使用基于Cookie的Session,在特定时间有大量用户访问服务器的时候,服务器就会面临需要存储大量Session ID在服务器里,但是如果有多台服务器,一个服务器存储了Session ID,又会面临需要分享Session ID给其他的服务器,因为可能出现服务器的超载,需要分配一些用户到其他服务器,其他服务器需要通用的Session ID才可以避免用户再次输入用户名和密码:

image-20220709102124913

2.但是服务器这样分享也不是办法,于是就让数据库存储Session ID,但是如果数据库崩溃了,又会影响从数据库获取Session ID:

image-20220709102433200

3.各种原因和需求的前提下,就出现了一种技术---JWT(Json Web Token),本质上就是一个Token:

image-20220709102648272

4.首先,用户第一次登陆网页以后,服务器就会生成一个JWT,服务器不用保存JWT,只需要JWT签名密文

image-20220709103133880

5.接着服务器把JWT发送给浏览器,可以让浏览器以Cookie或者Storage的形式进行存储,假设以Cookie的形式保存下来,这样用户每次发送请求都会把这个JWT发送给服务器,这样用户就不用重新输入账号密码了,和Seesion很类似,这里的Token(JWT)只不过存储在用户那边而已,当然会有人疑惑这个Token的安全性,那么下面我们看看它的组成。

image-20220709104324646

6.JWT是由三部分组成的:header、payload、signature:

image-20220709104501227

header:声明具体用什么算法生成签名。

payload:是一些特定的数据,比如有效期之类的。

image-20220709104644874

接着header和payload会经由Base64编码,注意是编码,不是加密,也就是说很容易可以解码,虽然JWT不保存在服务器这里,但是服务器要保存一段密码,这段密码要结合这两段编码进行算法运算,最终得到签名信息,这里使用的算法就是刚刚header中声明的算法,签名信息也就是刚才的signature部分了,这样一个完整的JWT就可以发送给客户端了。

image-20220709105340013

这里附带一个JWT解码网站:www.box3.cn/tools/jwt.h…

image-20220709105636776

通过这个我们可以看到,JWT是三个部分组成的,其中用 点号. 分割,分别代表了header payload signature三个部分,如果我们修改了三个部分中的任意字符,那么整个JWT都会失效:

image-20220709105843359

三个部分是相关联的,因此JWT具有一定的安全性,但是也不是那么安全,这里不再过多讲解。

总结:Session、Cookie和Token不是一个维度的东东,但是面试经常混合在一起问

Session是诞生并且保存在服务器那边的,由服务器主导一切,而Cookie则是一种数据载体,把Seesion放入Cookie中送到客户端那边

image-20220709110331105

Cookie保存在浏览器这边,跟随HTTP的每个请求发送出去

image-20220709110411547

Token是诞生在服务器,但保存在浏览器这边,由客户端主导一切,可以放在Cookie或者Storage里面,持有Token就像持有“令牌”一样可以允许访问服务器。

image-20220709110509389

如果忘记了想要复习,看这个原视频。

Cookie、Session、Token究竟区别在哪?如何进行身份认证,保持用户登录状态?哔哩哔哩bilibili

补充:跨站请求,伪造攻击:CRSF

image-20220709112751960

评论总结部分:

1.token生成于服务端,存储在客户端,服务端不用存储,用户后面每次登录都携带首次都登录生成的token字符串用于验证,能做到这点,关键就是token使用的某种算法根据用户签名和其它一些信息生成的令牌信息是一致的,可以验证通过,对于用户量庞大的系统,或者分布式,避免了大量session对象的存储带来的内存消耗,和各服务器之间session的复制或者专门用于存储session的服务器宕机带来的问题

2.JWT标准(也不能算标准吧,算范式?)里,token还真就是不在服务端存储的,是没有什么主动管理token的手段的,服务端只验证接受到的token的合法性(签名,时限,按一定规则写在token里),如果同时存储在服务端的缓存里,严格来说已经是经典session模式了。

3.token存在Redis里面可以实现踢人下线、解决单点登录等功能,会话数据可控,表述可能不当,详细可以查阅,区别在于从Redis中读取

4.token的本质就是个数据载体,服务端将原有的数据进行加密验签之后发布给用户,用以代表用户的身份标识,服务端可以根据用户token来解读里面的内容。而且至于存不存redis,如何与业务搭配实现单点登录都是项目开发的策略,跟token技术本身无关。

5.sessionid是存在服务器内存里,session保存的用户信息存在服务器内存或数据库, cookie接收保存服务器发来的sessionid,然后每次浏览器发送请求就会带上cookie的数据。 token是服务器加密的用户信息,服务器将token发给浏览器,浏览器用cookie或storage保存token。然后浏览器每次发送请求就带上token,服务器将其解密并确认用户登录。

6.服务器验证是前提。cookie保存在客户端,服务器不加密不保存;session保存在客户端,服务器要加密并保存(Session ID);token保存在客户端,服务器要加密不保存。

7.jwt就是token的一种实现,oauth2最广泛的就是你用qq登录B站, B站直接跳转给qq做登录,qq 返回给B站一个token和一些信息, B站通过这个token给你相对应的东西。

8.我一般开发的时候就采用Cookie+Token的组合,因为现在前后端分离的原因,Session+cookie机制已经好多年不用了。 用户登录后,后端拿用户的信息+客户端环境信息编码后使用AES算法加密,拿着加密后的字符串就可以直接当作令牌使用,把令牌储存到Redis里,随后返回用户的不敏感信息以及Token给前端,让前端储存到Cookie里,每次请求携带Token传给后端这样就可以做身份校验了。

9.cookie最早,既是验证机制,也是存储方式,验证信息存在本地,且可以由本地生成。 session,服务端生成,本地只存sessionid,sessionid由服务端生成,且验证信息存在服务端。 token,服务端生成,存在本地,相比与session只存一个id,本地存的信息更多,如header和payload,尤其是payload,可以确认用户信息。这样,服务端只要保证唯一密钥不丢失。每次都是临时通过header和payload配合密钥去生成signature验证用户身份的。 其实最重要的也就是signature,但是由于密钥只在服务端,如果本地token不泄露,其他人无法根据header和payload生成正确的signature,也无法通过修改payload去假冒其他用户或者篡改该用户的其他信息。

\