Cookie、Session和Token区别的理解

1 Cookie

Cookie其实就是浏览器保存在电脑中的一些文本数据,它们都是key-value形式的,其中包含了我们自己以及服务器的一些信息。当我们向一个服务器发送请求时,服务器可能希望我们在本地保存一些数据,这时候就会在响应报文的首部中加上一个名字叫做Set-Cookie(或Set-Cookie2,取决于版本)的首部行,后面跟着希望浏览器保存在本地的数据。浏览器接收到响应报文,发现了其中的set-Cookie字段,就会将其中包含的数据保存在电脑中,同时也记录下服务器的地址。那这些数据有什么用呢?当我们下一次向这个服务器发送请求时,这些Cookie数据就会随着请求报文一起被发往服务器,服务器接收到Cookie数据,就能以此识别当前发送请求的是哪一个客户端,或者说能够识别这个客户端,从而做出对应的响应操作。这个过程如下图所示:
在这里插入图片描述

由于Cookie是保存在本地文件中,所以它能够被长期保存,只需要将过期时间设置的长一些。这里还需要说明的是,由于Cookie将数据存储在本地,所以它其实是不安全的,因此浏览器允许客户端禁用Cookie。除此之外,Cookie能够保存的数据大小也有限制,单个Cookie保存的数据不能超过4K。
说到这里,应该知道了Cookie就是服务器委托浏览器存储在客户端里的一些数据,而这些数据通常都会记录用户的关键识别信息。所以Cookie需要用一些其他的手段用来保护,防止外泄或者窃取,这些手段就是Cookie的属性。
在这里插入图片描述

在这里插入图片描述

2 session

从字面上讲,就是会话。这个就类似于你和一个人交谈,你怎么知道当前和你交谈的是张三而不是李四呢?对方肯定有某种特征(长相等)表明他就是张三。

session 也是类似的道理,服务器要知道当前发请求给自己的是谁。为了做这种区分,服务器就要给每个客户端分配不同的“身份标识”,然后客户端每次向服务器发请求的时候,都带上这个“身份标识”,服务器就知道这个请求来自于谁了。至于客户端怎么保存这个“身份标识”,可以有很多种方式,对于浏览器客户端,大家都默认采用 cookie 的方式。

服务器使用session把用户的信息临时保存在了服务器上,用户离开网站后session会被销毁。这种用户信息存储方式相对cookie来说更安全,可是session有一个缺陷:如果web服务器做了负载均衡,那么下一个操作请求到了另一台服务器的时候session会丢失。

Session的中文翻译叫做:会话,表明它就是客户端与服务器的一次会话。与Cookie不一样,Session是由服务器进行维护的。当客户端向服务器发送一个请求时,服务器会为发起这个请求的客户端创建一个对象,并存储在服务器的一个集合中,同时生成一个唯一的SessionId来标识这个对象,而有关当前用户的信息可以存储在这个对象中。当服务器给用户发送响应报文时,也会将SessionId放入响应报文的Set-Cookie首部后,用户接收到响应报文后,检测当Set-Cookie首部行,将其中包含的SessionId存储在本地。在下一次客户端向服务器发出请求时,将SessionId从Cookie中读出,并发往服务器。服务器检测到SessionId后,在存储Session对象的集合中查找此SessionId对应的对象,即可获得用户的相关信息。最常见的一种用法就是用户登录:当用户登录后,服务器在Session中存储用户的身份信息,如userId。当接收到一个用户的请求后,查询Session对象,若其中包含userId,表示这个用户已经登录,同时可以通过获取到的userId查询用户私人的数据。而服务器并不会一直维护Session,它会在用户退出浏览器、或者在一段时间没有接收到这个用户的请求后,将Session清除。

在这里插入图片描述

但是,Session也存在一些问题,比如对于每一个用户,服务器都需要维护一个或多个Session,若一段时间内访问服务器的用户数量庞大,将导致服务器需要维护大量的Session对象,严重占用资源。除此之外,当今的Web服务器,都采用了集群的技术,集群中的每一台服务器的Session都是独立的,要实现Session共享也是一个比较麻烦的事情。最后再提一点,浏览器可以禁用Cookie,此时SessionId将无法存储在Cookie中,这个时候浏览器的一般做法是在URL中放入SessionId,这样在用户没有关闭网页之前,这个SessionId就不会丢失。

3 Token

Token的主要作用是对用户做身份验证,我们一般称它为:令牌。当我们要登录一个网站时,输入账号密码发送到服务器端。此时服务器查询数据库,验证账号密码,若验证成功,则服务器根据一些特殊的加密算法,计算出一个Token(一串字符),将其发送给客户端,同时将用户的身份信息也发送过去,比如userId。客户端接收到响应后,将Token存储在Cookie或者本地内存中,再次请求时将Token以及userId发送到服务器。服务器接收到一个请求后,根据客户端的相关信息,重新计算Token,若这个新的Token值与客户端发来的Token一致,表示用户之前已经经过验证,可以直接获取服务器数据。

是不是感觉和Session有些类似,但是实际上两者差别还是比较大的。服务器计算Token值需要用到用户的个人信息(比如说客户端的mac地址),以及只有服务器自己知晓的密匙,这也就保证了Token对于每一个客户端来说都是唯一的,而且由于密匙只有服务器自己知道,所以黑客无法模拟服务器计算Token值,然后发送虚假请求。服务器只要检测到错误的Token,就不会允许客户端的请求,而是要求客户端先进行验证。而且,对于每一个请求,服务器不需要像Session一样,保存客户端的身份信息,它每次只需要计算Token进行比较即可,也就是它不会破坏HTTP的无状态性。
  在这里插入图片描述

但是,这也意味着Token一旦被他人截获,对方就可以使用你的身份,对服务器发出请求。所以,Token一般都是基于HTTPS使用,而不是基于不安全的HTTP使用。而且存储在本地时,也会进行相应的加密处理。
  基于Token的验证原理
  基于Token的身份验证是无状态的,我们不将用户信息存在服务器或Session中。

这种概念解决了在服务端存储信息时的许多问题

NoSession意味着你的程序可以根据需要去增减机器,而不用去担心用户是否登录。

基于Token的身份验证的过程如下:

用户通过用户名和密码发送请求。

程序验证。

程序返回一个签名的token 给客户端。

客户端储存token,并且每次用于每次发送请求。

服务端验证token并返回数据。

每一次请求都需要token。token应该在HTTP的头部发送从而保证了Http请求无状态。我们同样通过设置服务器属性Access-Control-Allow-Origin:* ,让服务器能接受到来自所有域的请求。需要主要的是,在ACAO头部标明(designating)*时,不得带有像HTTP认证,客户端SSL证书和cookies的证书。

实现思路:
在这里插入图片描述

用户登录校验,校验成功后就返回Token给客户端。

客户端收到数据后保存在客户端

客户端每次访问API是携带Token到服务器端。

服务器端采用filter过滤器校验。校验成功则返回请求数据,校验失败则返回错误码

当我们在程序中认证了信息并取得token之后,我们便能通过这个Token做许多的事情。

我们甚至能基于创建一个基于权限的token传给第三方应用程序,这些第三方程序能够获取到我们的数据(当然只有在我们允许的特定的token)

Tokens的优势

无状态、可扩展

在客户端存储的Tokens是无状态的,并且能够被扩展。基于这种无状态和不存储Session信息,负载负载均衡器能够将用户信息从一个服务传到其他服务器上。

如果我们将已验证的用户的信息保存在Session中,则每次请求都需要用户向已验证的服务器发送验证信息(称为Session亲和性)。用户量大时,可能会造成

一些拥堵。

但是不要着急。使用tokens之后这些问题都迎刃而解,因为tokens自己hold住了用户的验证信息。

安全性

请求中发送token而不再是发送cookie能够防止CSRF(跨站请求伪造)。即使在客户端使用cookie存储token,cookie也仅仅是一个存储机制而不是用于认证。不将信息存储在Session中,让我们少了对session操作。

token是有时效的,一段时间之后用户需要重新验证。我们也不一定需要等到token自动失效,token有撤回的操作,通过token revocataion可以使一个特定的token或是一组有相同认证的token无效。

可扩展性()

Tokens能够创建与其它程序共享权限的程序。例如,能将一个随便的社交帐号和自己的大号(Fackbook或是Twitter)联系起来。当通过服务登录Twitter(我们将这个过程Buffer)时,我们可以将这些Buffer附到Twitter的数据流上(we are allowing Buffer to post to our Twitter stream)。

使用tokens时,可以提供可选的权限给第三方应用程序。当用户想让另一个应用程序访问它们的数据,我们可以通过建立自己的API,得出特殊权限的tokens。

多平台跨域

我们提前先来谈论一下CORS(跨域资源共享),对应用程序和服务进行扩展的时候,需要介入各种各种的设备和应用程序。

4 cookie、session与token之间的关系

4.1 图解流程

在这里插入图片描述
在这里插入图片描述Cookie的传递流程:

1.浏览器向某个URL发起HTTP请求(可以是任何请求,比如GET一个页面、POST一个登录表单、DELETE某条评论、PUT某条更新等)

2.对应的服务器收到该HTTP请求,并计算应当返回给浏览器的HTTP响应(HTTP响应包括请求头和请求体两部分)

3.在响应头加入Set-Cookie字段,它的值是要设置的Cookie。

4.浏览器收到来自服务器的HTTP响应。

5.浏览器在响应头中发现Set-Cookie字段,就会将该字段的值保存在内存或者硬盘中(Set-Cookie字段的值可以是很多项Cookie,每一项都可以指定过期时间Expires。 默认的过期时间是用户关闭浏览器时。)

6.浏览器下次给该服务器发送HTTP请求时, 会将服务器设置的Cookie附加在HTTP请求的头字段Cookie中。(浏览器可以存储多个域名下的Cookie,但只发送当前请求的域名曾经指定的Cookie, 这个域名也可以在Set-Cookie字段中指定)。)

7.服务器收到这个HTTP请求,发现请求头中有Cookie字段, 便知道之前就和这个用户打过交道了.

8.过期的Cookie会被浏览器删除。

总之,服务器通过Set-Cookie响应头字段来指示浏览器保存Cookie, 浏览器通过Cookie请求头字段来告诉服务器之前的状态。 Cookie中包含若干个键值对,每个键值对可以设置过期时间。

session的传递流程:

1.用户提交包含用户名和密码的表单,发送HTTP请求。

2.服务器验证用户发来的用户名密码。

3.如果正确则把当前用户名(通常是用户对象)存储到redis中,并生成它在redis中的ID。这个ID称为Session ID,通过Session ID可以从Redis中取出对应的用户对象, 敏感数据(比如authed=true)都存储在这个用户对象中。

4.设置Cookie为sessionId=xxxxxx|checksum并发送HTTP响应, 仍然为每一项Cookie都设置签名。

5.用户收到HTTP响应后,便看不到任何敏感数据了。在此后的请求中发送该Cookie给服务器。

6.服务器收到此后的HTTP请求后,发现Cookie中有SessionID,进行放篡改验证。

7.如果通过了验证,根据该ID从Redis中取出对应的用户对象, 查看该对象的状态并继续执行业务逻辑。实现上述过程,在Web应用中可以直接获得当前用户。 相当于在HTTP协议之上,通过Cookie实现了持久的会话。这个会话便称为Session。
使用Token的方法

不是在每一次请求时提供用户名和密码的凭证。我们可以让用户通过token交换凭证(we can allow the client to exchange valid credentials for a token),这个token提供用户访问服务器的权限。Token通常比密码更加长而且复杂。比如说,JWTs通常会应对长达150个字符。一旦获得了token,在每次调用API的时候都要附加上它。然后,这仍然比直接发送账户和密码更加安全,哪怕是HTTPS。

把token想象成一个安全的护照。你在一个安全的前台验证你的身份(通过你的用户名和密码),如果你成功验证了自己,你就可以取得这个。当你走进大楼的时候(试图从调用API获取资源),你会被要求验证你的护照,而不是在前台重新验证。

获取一个Token我们需要做的第一件事就是让客户端通过他们的账号密码交换token。这里有2种可能的方法在RESTful API里面。第一种是使用POST请求来通过验证,使服务端发送带有token的响应。除此之外,你可以使用GET请求,这需要他们使用参数提供凭证(指URL),或者更好的使用请求头。

4.2 Cookie、Session和Token

token
令牌,是用户身份的验证方式。
最简单的token组成:uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名)。
对Token认证的五点认识

一个Token就是一些信息的集合;
在Token中包含足够多的信息,以便在后续请求中减少查询数据库的几率;
服务端需要对cookie和HTTP Authrorization Header进行Token信息的检查;
基于上一点,你可以用一套token认证代码来面对浏览器类客户端和非浏览器类客户端;
因为token是被签名的,所以我们可以认为一个可以解码认证通过的token是由我们系统发放的,其中带的信息是合法有效的;

session
会话,代表服务器与浏览器的一次会话过程,这个过程是连续的,也可以时断时续。
cookie中存放着一个sessionID,请求时会发送这个ID;
session因为请求(request对象)而产生;
session是一个容器,可以存放会话过程中的任何对象;
session的创建与使用总是在服务端,浏览器从来都没有得到过session对象;
session是一种http存储机制,目的是为武装的http提供持久机制。

cookie
储存在用户本地终端上的数据,服务器生成,发送给浏览器,下次请求统一网站给服务器。

4.3 区别

cookie与session区别

安全性: Session 比 Cookie 安全,Session 是存储在服务器端的,Cookie 是存储在客户端的。
存取值的类型不同:Cookie 只支持存字符串数据,想要设置其他类型的数据,需要将其转换成字符串,Session 可以存任意数据类型。
有效期不同: Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能,Session
一般失效时间较短,客户端关闭(默认情况下)或者 Session 超时都会失效。 存储大小不同: 单个 Cookie 保存的数据不能超过
4K,Session 可存储数据远高于 Cookie,但是当访问量过多,会占用过多的服务器资源。

session与token

Session 是一种记录服务器和客户端会话状态的机制,使服务端有状态化,可以记录会话信息。而 Token是令牌,访问资源接口(API)时所需要的资源凭证。Token 使服务端无状态化,不会存储会话信息。
Session 和 Token并不矛盾,作为身份认证 Token 安全性比 Session 好,因为每一个请求都有签名还能防止监听以及重放攻击,而 Session 就必须依赖链路层来保障通讯安全了。如果你需要实现有状态的会话,仍然可以增加 Session 来在服务器端保存一些状态。
所谓 Session 认证只是简单的把 User 信息存储到 Session 里,因为 SessionID 的不可预测性,暂且认为是安全的。而 Token,如果指的是 OAuth Token 或类似的机制的话,提供的是 认证 和 授权 ,认证是针对用户,授权是针对 App 。其目的是让某 App 有权利访问某用户的信息。这里的 Token 是唯一的。不可以转移到其它 App上,也不可以转到其它用户上。Session 只提供一种简单的认证,即只要有此 SessionID ,即认为有此 User 的全部权利。是需要严格保密的,这个数据应该只保存在站方,不应该共享给其它网站或者第三方 App。所以简单来说:如果你的用户数据可能需要和第三方共享,或者允许第三方调用 API 接口,用 Token 。如果永远只是自己的网站,自己的 App,用什么就无所谓了。

token与cookie

Cookie是不允许垮域访问的,但是token是支持的, 前提是传输的用户认证信息通过HTTP头传输;

token就是令牌,比如你授权(登录)一个程序时,他就是个依据,判断你是否已经授权该软件;cookie就是写在客户端的一个txt文件,里面包括你登录信息之类的,这样你下次在登录某个网站,就会自动调用cookie自动登录用户名;session和cookie差不多,只是session是写在服务器端的文件,也需要在客户端写入cookie文件,但是文件里是你的浏览器编号.Session的状态是存储在服务器端,客户端只有session
id;而Token的状态是存储在客户端。

HTTP协议与状态保持:Http是一个无状态协议
什么是 JWT
JSON Web Token(简称 JWT)是目前最流行的跨域认证解决方案。
是一种认证授权机制。
JWT 是为了在网络应用环境间传递声明而执行的一种基于 JSON 的开放标准(RFC 7519)。JWT 的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源。比如用在用户登录上。
可以使用 HMAC 算法或者是 RSA 的公/私秘钥对 JWT 进行签名。因为数字签名的存在,这些传递的信息是可信的。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值