session cookie token 及 ajax 中如何应用

概述:

cookie 验证准确的说是利用 cookie 来作为媒介,存储 session ID 进行验证,下文中提到的 cookie 验证主要是指 session ID 存储到 cookie 中,携带在请求头中进行验证

token 其实也可以借助 cookie 来存储,token 验证主要是指 token 存储到 localStorage / sessionStorage / cookie 中,携带在请求头中的 Authorization 进行验证。

首先明确http是无状态的:它就像一个机器一样,只知道机械地运转,但无法区分是谁在控制它,是谁在请求它,通过这两种验证方式可以让 http 分辨出哪些是可信任的。

session

Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。

每个用户访问服务器都会建立一个session,那服务器是怎么标识用户的唯一身份呢?事实上,用户与服务器建立连接的同时,服务器会自动为其分配一个SessionId。

本来 session 是一个抽象概念,开发者为了实现中断和继续等操作,将 user agent 和 server 之间一对一的交互,抽象为“会话”,进而衍生出“会话状态”,也就是 session 的概念。

而我们今天常说的 “session”,是为了绕开 cookie 的各种限制,通常借助 cookie 本身和后端存储实现的,一种更高级的会话状态实现。

cookie

cookie本质上是实现了session,通过建立客户端和服务端的会话,客户端和服务端都保存session ID,这样做每次请求时,服务端都要去数据库中找一下是否有这个人。

cookie 是一个实际存在的东西,http 协议中定义在 header 中的字段。可以认为是 session 的一种后端无状态实现。

假如我们要去迪士尼玩耍,cookie机制就相当于,我们去之前,需要在网上提前买好票,这样我们进园时,保安手里就有一份买了票的人员名单,他需要在每个人进园的时候,在这份名单里查找一下有没有这个人,如果有,那你就可以进去,否则,你就得即刻买票。

过程:

  1. 客户端发送账号和密码(可用 window.btoa() 转码密码);
  2. 服务端接收后,在数据库里找一下有没有这个账号和密码,如果没有找到的话,就创建一个 session,存入数据库,并把 session ID 放进 cookie 中,返回给客户端;
  3. 客户端收到后,把 session ID 存起来,每次发起其他请求,都带上这个 session ID 放在请求头中;
  4. 服务端收到后,在数据库中查找 session ID 对应的 session,如果找到了,说明这个用户就通过了验证,服务端就认识了,返回相应的数据。
  5. 一旦用户登出,则 session 在客户端和服务器端都被销毁。
ajax请求携带cookie和自定义请求头header(跨域和同域):
  • 同域请求下,ajax会自动带上同源的cookie;
  • 跨域请求下,ajax不会自动携带同源的cookie,需要通过前端配置相应参数才可以跨域携带同源cookie,后台配置相应参数才可以跨域返回同源cookie;
    前端参数withCredentials: true
    后台参数Access-Control-Allow-Origin:Access-Control-Allow-Credentials:

配置了Access-Control-Allow-Credentials:true则不能设置Access-Control-Allow-Origin:*

session 和 cookie 的区别

  1. cookie数据存放在客户的浏览器上,session数据放在服务器上。
  2. cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session。
  3. session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用cookie。
  4. 单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
  5. 可以考虑将登陆信息等重要信息存放为session,其他信息如果需要保留,可以放在cookie中。

token

token 则不需要建立 session,不建立会话,而是通过携带“令牌”,告诉服务端“我是你的同事”,我可以要求你做一些事情。

token 放在了 请求头 中的 Authorization,形式是 Bearer { JWT },但是也可以在 post body 里发送,甚至作为 query parameter。

过程:

  1. 客户端发送账号和密码(可用 window.btoa() 转码密码);
  2. 服务端接收后,生成一个 token,返回给客户端,但自己不保存;
  3. 客户端收到后,把 token 存起来,大多数通常在 local storage,但是也可以存储在 session storage 或者 cookie 中,每次操作都带上这个 token;
  4. 客户端又发起其他请求,将 token 放进请求头中的 Authorization
  5. 服务器端解码 JWT 然后验证 token,如果 token 有效,说明这个用户就通过了验证,服务端就认识了,返回相应的数据。

同样去迪士尼玩耍,token机制就相当于,我们去之前,需要在网上提前买好票,然后我们拿到一份对应的二维码,这样我们进园时,直接扫二维码,成功可以进去,否则,你就得即刻买票。
不需要保安找我们的名字,实现了智能化,也就是无状态。

ajax添加Token到Header中的方法:
$.ajax({
    type: "GET",
    url: "/access/logout/" + userCode,
    headers: {'Authorization': token}
})
$.ajax({
    type: "GET",
    url: "/access/logout/" + userCode,
    beforeSend: function(request) {
        request.setRequestHeader("Authorization", token);
    },
    success: function(result){}
})

token 相对 cookie 的优势

  1. 支持跨域访问 ,将token置于请求头中,而cookie是不支持跨域访问的;
  2. 无状态化, 服务端无需存储token ,只需要验证token信息是否正确即可,而session需要在服务端存储,一般是通过cookie中的sessionID在服务端查找对应的session;
  3. 无需绑定到一个特殊的身份验证 方案(传统的用户名密码登陆),只需要生成的token是符合我们预期设定的即可;
  4. 更适用于移动端 (Android,iOS,小程序等等),像这种原生平台不支持cookie,比如说微信小程序,每一次请求都是一次会话,当然我们可以每次去手动为他添加cookie;
  5. 避免CSRF跨站伪造攻击 ,还是因为不依赖cookie;
  6. 非常适用于RESTful API ,这样可以轻易与各种后端(java,.net,python…)相结合,去耦合

参考:https://www.jianshu.com/p/c33f5777c2eb

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值