Bootstrap

cookie、session、token、JWT的解释

什么是Cookies?

Cookies是一些数据,存储于我们电脑上的文本文件中。由于cookie多用于在客户端和服务端交互通信,所以前后端语言都可存取cookie(例如前端JavaScript,后端PHP)。当web服务器向浏览器发送web页面时,在连接关闭后,服务端不会记录用户的信息。Cookies的作用就是用于解决“如何记录客户端的用户信息”

  1. 当用户访问web页面时,用户的名字可以记录在Cookies中。
  2. 在用户下一次访问该页面时,可以在Cookies中读取用户的访问记录。
一、Cookies存储方式

Cookies是以名/值对的形式存储。例如:

username=XiaoMing

当浏览器从服务器上请求web页面时,属于该页面的Cookies会被添加到请求中。服务端通过这种方式来获取用户的信息。

二、使用JavaScript来操作Cookies

JavaScript可以使用document.cookie属性来创建、读取、及删除cookies。

创建
  1. 创建Cookies.
document.cookie="username=XiaoMing";
  1. 我们同时可以为cookie设置一个过期时间(expires属性,为UTC或GMT格式)。默认情况下,cookie在浏览器关闭时删除:
document.cookie="username=XiaoMing;expires=Thu,18 Dec 2013 12:00:00 GMT"
  1. 还可以使用path参数告诉浏览器cookie存放的路径。默认情况下是当前的页面。
document.cookie="username=XiaoMing;expires=Thu,18 Dec 2013 12:00:00 GMT;path=/"
读取
  1. 我们可以用JavaScript来读取cookie。例如:
var cookieData=document.cookie;
  1. **注意:**document.cookie将以字符串的格式返回所有cookies。例如:
cookie1=value;cookie2=value;cookie3=value;
修改
  1. 在Javascript中,修改cookie类似于创建cookies。例如:
document.cookie="username=LiangJingRu;expires=Thu,18 Dec 2013 12:00:00 GMT;path=/"

这样旧的cookie将被覆盖。

删除
  1. 删除cookie非常简单,只需将过期时间设置为一个已过去的时间即可。
document.cookie="username=;expires=Thu,05 Jan 2015 00:00:00 GMT";
  1. 注意: 当想删除时不必指定cookie的值。username就没有指定值。
三、Cookie字符串
  1. document.cookie属性不是一个普通的文本字符串。即使我们在document.cookie中写入一个完整的cookie字符串,当我们重新读取该cookie信息时,cookie信息是以名/值对的形式展示的。如果您设置了新的cookie(新的cookie指的是,cookie中的名称是新的。),则旧的cookie不会被覆盖,新cookie将添加到document.cookie中,所有当重新读取document.cookie时,会显示:
cookie1=value;cookie2=value;cookie3=value;
  1. 如何在这么多cookies中,找到一个指定的cookie?我们可以用一个函数,在Cookie字符串中查找cookie值。
四、示例
  1. 在这个例子,我将创建cookie来存储访问web页面的访问者的用户名。
  2. 首先,访问者访问web页面,访问者被要求填写自己的名字,该名字将会存储在cookie中。
  3. 访问者下一次访问页面时,他将会看到一个欢迎的消息。
在这个示例中,需要创建三个JavaScript函数:
  1. 设置cookie值的函数
setCookie(cookieName,cookieValue,cookieExpires){
       	var date=new Date();
       	date.setTime(date.getTime()+(cookieExpires*24*60*60*1000));
       	var expires="expires="+date.toUTCString();//变量expires成为了UTC格式的时间字符串
       	document.cookie=cookieName+"="+cookieValue+";"+"expires="+cookieExpires;
  }

上示函数的参数:cookieName是cookie的名称,cookieValue是cookie的值,cookieExpires是cookie的过期时间。
2. 获取cookie值的函数

getCookie(cookieName){
      var name=cookieName+"=";
      var array=document.cookie.split(';');//document.cookie返回的是带有以‘;’分隔的字符串,运用split()将其转换为数组
      for(var i=0;i<array.length;i++){
          var en=array[i].trim();//去除数组值中的前后空格,避免因空格导致找不到值
          if(en.indexOf(name)==0){//index()是返回en变量中第一次出现name字符串的下标,因为cookie值是以名/值对返回,所以“名”是在变量en的0下标可以匹配。
                 return en.substring(name.length,en.length);//参数分别为子字符串开始的下标以及结束的下标;返回字符串对象中指定位置的子字符串。
          }
       }
      return "";
  }

如果找到,则返回cookieName对应的值;否则返回空
3. 检测cookie值的函数

checkCookie(){
    var userName=this.getCookie("userName");
    if(userName!=""){
      alert("欢迎"+userName+"再次到来");
     }else{
       userName=prompt("请填写你的姓名:","");//prompt()方法用于显示可提示用户进行输入的对话框。返回用户输入的内容;第一个参数是在对话框显示的文本,第二个参数是默认的输入文本
       if(userName!=""&&userName!=null){
         this.setCookie("userName",userName,30);
      }
    }
  }

如果设置了cookie,则会弹出一个问候消息;否则弹出一个弹窗,用于询问访问者姓名,并设置cookie和有效时间为30天。
4.在chorme的控制台查看cookie
在这里插入图片描述

五、Cookie注意事项
  1. cookie有大小限制,一般每个cookie不超过4kb,如果超过则cookie属性返回空。
  2. cookie存放在我们的电脑的文本中,容易被查看和修改,因此,不要存放重要的隐私消息。
  3. cookie的域概念(domain):因为浏览器需要有个安全的环境,所以不同的域是不能互相访问cookie的(除非设置什么来跨域访问)。
  4. cookie的路径:一个网页创建的cookie只能被与这个网页在同一目录或子目录下的网页访问,而不能被其它目录下的网页访问。
  5. 一个网站可以创建第一个cookie,都存在同一个文件中。
  6. cookie 无法跨域
六、详细讲解Cookie的域概念与路径概念

路径概念(routing):

  1. cookie一般在用户访问web页面被创建,但是该创建的cookie并不是只能在该页面才能被访问。默认情况下,只要与创建cookie的页面是同一个目录或者是该目录下的子目录页面都可以访问该cookie。
  2. 举个例子:在“http://www.abc.com/boke/”这个页面创建cookie,则在“/boke/”这个路径下的子目录,例:“http://www.abc.com/boke/efc.html”都可以访问上面的cookie。那么“http://www.abc.com”或者“http://www.abc.com/xxx/”都不可以访问上面的cookie。
  3. 那么怎样才能让上级目录和其它目录页面访问上面的cookie?只需将cookie的路径path设在(’/’)根目录即可。这样所有的页面都可以访问该cookie。

域概念(domain):

  1. 路径能解决同一个域下共享cookie,但同域之间要怎样实现cookie共享呢?
  2. 所谓的“同域”:例www.abc.com和xxx.abc.com公用一个有关联的域名“abc.com”,那么www.abc.com和xxx.abc,com要共享cookie,则需要用到cookie的domain属性,同时需将路径path设为根目录。
document.cookie="userName=XiaoMing;path=/;domain=abc.com";
七、cookie安全性

通常cookie是通过http连接传递数据,但http是无安全传输数据,容易被盗取cookie。要做到对数据加密,则要设置cookie的secure属性。如果cookie设置了secure,则前后端交互就会通过https或其它其他安全协议传输数据。

document.cookie="userName=XiaoMing;secure";

注意: 加入了secure,仅仅只是对传输过程的cookie加密。自己主机的cookie并不会被加密。

什么是Session

  1. session是另一种记录服务器和客户端会话记录的机制,是服务端有状态化
  2. session是以cookie为基础来实现的,session存储在服务器端,sessionId作为session唯一标识符,sessionId会被存储到客户端的cookie中。
一、session的认证流程:
  1. 在用户第一次向服务器发起请求,服务器会根据用户提交的信息,创建对应的Session。
  2. 这个请求会返回此Session的唯一标识符SessionId给客户端。
  3. 客户端收到响应信息后,会将SessionId信息存入Cookie中,同时Cookie也记录着SessionId属于哪个域名。
  4. 此后,在Cookie有效的时间发起请求,请求会自动判断此域名是否存在Cookie信息中,如果存在,则自动将Cookie信息一并发送给服务端,因为SessionId存在Cookie中,所以服务端也就获得了SessionId,根据SessionId查找对应的Session信息,如果能找到对应Session信息,则可执行更深入的操作,否则说明该用户不存在或登录失效。
    在这里插入图片描述
  5. 目前session大多数系统用来验证用户登录状态。
二、Cookie和Session的差异
  1. 存储容量:已知Cookie容量不超过4kb,但session的容量远大于cookie,但别忘了session存储在服务端,session容量过大,会影响服务器的性能。
  2. 有效时间:Cookie的有效时间可设置长点。
  3. 存取数据类型不同:Cookie只支持字符串类型,而Session可以为任意类型。
  4. 安全方面:由于Session存储于服务端,则Session更加安全。

什么是Token

一、Access Token(访问令牌)
  1. Token一般由uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名)组成。
  2. 是访问API时需要的资源凭证。
  3. 支持在移动端设备使用。
  4. token认证是一种服务端无状态认证方式,服务端没有存放token数据。服务端在接收请求时,用算法解析token来认证,用解析token所花费的时间来代替了session所花费的存储空间,因为当session存储于数据库,每次认证都查询数据库匹配sessionId,造成数据库压力过大。
二、token的认证流程
  1. 用户在客户端使用用户名和密码请求登录。
  2. 服务端收到请求,验证用户名和密码。
  3. 验证成功后,服务端会签发一个 token 并把这个 token 返回给客户端。
  4. 客户端收到token,会把它存储在cookie或者localStorage里。
  5. 当客户端获得token之后,再向服务端请求数据时,都需要用刚返回的token作为资源凭证。每一次请求都需要把token放在Http的Header里。
  6. 服务端收到请求,然后去验证请求里携带着的token,如果验证成功,就向客户端返回请求的数据。

在这里插入图片描述

三、Refresh Token(刷新令牌)
  1. 这是另一种token。
  2. refresh token的作用仅仅用于刷新access token的token以生成新的access token。如果不是用refresh token去刷新token,则每次刷新都要用户输入用户名和密码,这给用户的体验非常不好。通过refresh token则无需用户做多余的操作。
  3. 通常Access token的有效期比较短,当Access token失效了,可以用refresh token去刷新Access token,只有当refresh token失效了,用户才需重新登陆账号。
  4. refresh token以及过期时间是存储在数据库中,只有申请新的Access token时才会去验证。
四、session和token的差异
  1. token安全性更高,每次请求都需要token。
  2. session使服务端和客户端通讯有状态化,而token是无状态化。
  3. 使用token,可以降低数据库压力。

什么是JWT(重点)

JWT是JSON Web Token的简称,是当前最流行的跨域认证解决方案。JWT的声明一般用在身份提供者和服务提供者间传递被认证的用户信息,以便从服务器获得数据资源。例如用在用户登录上。

一、JWT认证流程
  1. 用户从客户端发送用户名和密码,服务端认证后会返回给客户端一个JWT,客户端将token保存在cookie或者localStorage中。
  2. 当服务端接收到请求,服务端会检查请求的header中的Authorization中的JWT信息,如果认证成功,则可以继续访问资源。
  3. 因为JWT的使用不用到cookie,所以你可以使用任何域名来提供你的API服务,这就说明不用担心CORS(跨域资源共享问题)。
二、3种使用方式
  1. 当用户希望访问一个受保护的资源,需要在请求的header的Authorization字段中使用Bearer模式来添加JWT。即:Authorization:Bearer;
  2. 跨域的时候,可以把JWT放在Post请求的数据体里。
  3. 通过URL传输:http://www.abc.com/user?token=xxx
;