Token ,Cookie和Session的区别

在作接口测试时,常常会碰到请求参数为token的类型,可是可能大部分测试人员对token,cookie,session的区别仍是只知其一;不知其二。mysql

 

cookie 是一个很是具体的东西,指的就是浏览器里面能永久存储的一种数据,仅仅是浏览器实现的一种数据存储功能。web

cookie由服务器生成,发送给浏览器,浏览器把cookie以kv形式保存到某个目录下的文本文件内,下一次请求同一网站时会把该cookie发送给服务器。因为cookie是存在客户端上的,因此浏览器加入了一些限制确保cookie不会被恶意使用,同时不会占据太多磁盘空间,因此每一个域的cookie数量是有限的。redis

Session

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

session 也是相似的道理,服务器要知道当前发请求给本身的是谁。为了作这种区分,服务器就要给每一个客户端分配不一样的“身份标识”,而后客户端每次向服务器发请求的时候,都带上这个“身份标识”,服务器就知道这个请求来自于谁了。至于客户端怎么保存这个“身份标识”,能够有不少种方式,对于浏览器客户端,你们都默认采用 cookie 的方式。sql

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

Token

Token的引入:Token是在客户端频繁向服务端请求数据,服务端频繁的去数据库查询用户名和密码并进行对比,判断用户名和密码正确与否,并做出相应提示,在这样的背景下,Token便应运而生。后端

Token的定义:Token是服务端生成的一串字符串,以做客户端进行请求的一个令牌,当第一次登陆后,服务器生成一个Token便将此Token返回给客户端,之后客户端只需带上这个Token前来请求数据便可,无需再次带上用户名和密码。最简单的token组成:uid(用户惟一的身份标识)、time(当前时间的时间戳)、sign(签名,由token的前几位+盐以哈希算法压缩成必定长的十六进制字符串,能够防止恶意第三方拼接token请求服务器)。api

使用Token的目的:Token的目的是为了减轻服务器的压力,减小频繁的查询数据库,使服务器更加健壮。浏览器

 

传统身份验证

HTTP 是一种没有状态的协议,也就是它并不知道是谁是访问应用。这里咱们把用户当作是客户端,客户端使用用户名还有密码经过了身份验证,不过下回这个客户端再发送请求时候,还得再验证一下。安全

解决的方法就是,当用户请求登陆的时候,若是没有问题,咱们在服务端生成一条记录,这个记录里能够说明一下登陆的用户是谁,而后把这条记录的 ID 号发送给客户端,客户端收到之后把这个 ID 号存储在 Cookie 里,下次这个用户再向服务端发送请求的时候,能够带着这个 Cookie ,这样服务端会验证一个这个 Cookie 里的信息,看看能不能在服务端这里找到对应的记录,若是能够,说明用户已经经过了身份验证,就把用户请求的数据返回给客户端。

上面说的就是 Session,咱们须要在服务端存储为登陆的用户生成的 Session ,这些 Session 可能会存储在内存,磁盘,或者数据库里。咱们可能须要在服务端按期的去清理过时的 Session 。

基于 Token 的身份验证

使用基于 Token 的身份验证方法,在服务端不须要存储用户的登陆记录。大概的流程是这样的:

  • 客户端使用用户名跟密码请求登陆
  • 服务端收到请求,去验证用户名与密码
  • 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
  • 客户端收到 Token 之后能够把它存储起来,好比放在 Cookie 里或者 Local Storage 里
  • 客户端每次向服务端请求资源的时候须要带着服务端签发的 Token
  • 服务端收到请求,而后去验证客户端请求里面带着的 Token,若是验证成功,就向客户端返回请求的数据

APP登陆的时候发送加密的用户名和密码到服务器,服务器验证用户名和密码,若是成功,以某种方式好比随机生成32位的字符串做为token,存储到服务器中,并返回token到APP,之后APP请求时,凡是须要验证的地方都要带上该token,而后服务器端验证token,成功返回所须要的结果,失败返回错误信息,让他从新登陆。其中服务器上token设置一个有效期,每次APP请求的时候都验证token和有效期。

那么个人问题来了: 1.服务器上的token存储到数据库中,每次查询会不会很费时。若是不存储到数据库,应该存储到哪里呢。 2.客户端获得的token确定要加密存储的,发送token的时候再解密。存储到数据库仍是配置文件呢?

token是个易失数据,丢了无非让用户从新登陆一下,新浪微博动不动就让我从新登陆,反正这事儿我是无所谓啦。
因此若是你以为普通的数据库表撑不住了,能够放到 MSSQL/MySQL 的内存表里(不过听说mysql的内存表性能提高有限),能够放到 Memcache里(讲真,这个是挺常见的策略),能够放到redis里(我作过这样的实现),甚至能够放到 OpenResty 的变量字典里(只要你有信心不爆内存)。

token是个凭条,不过它比门票温柔多了,门票丢了从新花钱买,token丢了从新操做下认证一个就能够了,所以token丢失的代价是能够忍受的——前提是你别丢太频繁,要是让用户隔三差五就认证一次那就损失用户体验了。

基于这个出发点,若是你认为用数据库来保持token查询时间太长,会成为你系统的瓶颈或者隐患,能够放在内存当中。
好比memcached、redis,KV方式很适合你对token查询的需求。
这个不会太占内存,好比你的token是32位字符串,要是你的用户量在百万级或者千万级,那才多少内存。
要是数据量真的大到单机内存扛不住,或者以为一宕机全丢风险大,只要这个token生成是足够均匀的,高低位切一下分到不一样机器上就行,内存绝对不会是问题。

客户端方面这个除非你有一个很是安全的办法,好比操做系统提供的隐私数据存储,那token确定会存在泄露的问题。好比我拿到你的手机,把你的token拷出来,在过时以前就均可以以你的身份在别的地方登陆。
解决这个问题的一个简单办法
一、在存储的时候把token进行对称加密存储,用时解开。
二、将请求URL、时间戳、token三者进行合并加盐签名,服务端校验有效性。
这两种办法的出发点都是:窃取你存储的数据较为容易,而反汇编你的程序hack你的加密解密和签名算法是比较难的。然而其实说难也不难,因此终究是防君子不防小人的作法。话说加密存储一个你要是被人扒开客户端看也不会被喷明文存储……
方法1它拿到存储的密文解不开、方法2它不知道你的签名算法和盐,二者能够结合食用。
可是若是token被人拷走,他天然也能植入到本身的手机里面,那到时候他的手机也能够以你的身份来用着,这你就瞎了。
因而能够提供一个让用户能够主动expire一个过去的token相似的机制,在被盗的时候能远程止损。

在网络层面上token明文传输的话会很是的危险,因此建议必定要使用HTTPS,而且把token放在post body里。

 

补充:

cookie与session的区别

一、cookie数据存放在客户端上,session数据放在服务器上。

二、cookie不是很安全,别人能够分析存放在本地的COOKIE并进行COOKIE欺骗
   考虑到安全应当使用session。

三、session会在必定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
   考虑到减轻服务器性能方面,应当使用COOKIE。

四、单个cookie保存的数据不能超过4K,不少浏览器都限制一个站点最多保存20个cookie。

五、因此我的建议:
   将登录信息等重要信息存放为SESSION
   其余信息若是须要保留,能够放在COOKIE中

 

session与token的区别

  session 和 oauth token并不矛盾,做为身份认证 token安全性比session好,由于每一个请求都有签名还能防止监听以及重放攻击,而session就必须靠链路层来保障通信安全了。如上所说,若是你须要实现有状态的会话,仍然能够增长session来在服务器端保存一些状态

  App一般用restful api跟server打交道。Rest是stateless的,也就是app不须要像browser那样用cookie来保存session,所以用session token来标示本身就够了,session/state由api server的逻辑处理。 若是你的后端不是stateless的rest api, 那么你可能须要在app里保存session.能够在app里嵌入webkit,用一个隐藏的browser来管理cookie session.

  Session 是一种HTTP存储机制,目的是为无状态的HTTP提供的持久机制。所谓Session 认证只是简单的把User 信息存储到Session 里,由于SID 的不可预测性,暂且认为是安全的。这是一种认证手段。 而Token ,若是指的是OAuth Token 或相似的机制的话,提供的是 认证 和 受权 ,认证是针对用户,受权是针对App 。其目的是让 某App有权利访问 某用户 的信息。这里的 Token是惟一的。不能够转移到其它 App上,也不能够转到其它 用户 上。 转过来讲Session 。Session只提供一种简单的认证,即有此 SID,即认为有此 User的所有权利。是须要严格保密的,这个数据应该只保存在站方,不该该共享给其它网站或者第三方App。 因此简单来讲,若是你的用户数据可能须要和第三方共享,或者容许第三方调用 API 接口,用 Token 。若是永远只是本身的网站,本身的 App,用什么就无所谓了。

 

打破误解:

只要关闭浏览器 ,session就消失了?

不对。对session来讲,除非程序通知服务器删除一个session,不然服务器会一直保留,程序通常都是在用户作log off的时候发个指令去删除session。

然而浏览器历来不会主动在关闭以前通知服务器它将要关闭,所以服务器根本不会有机会知道浏览器已经关闭,之因此会有这种错觉,是大部分session机制都使用会话cookie来保存session id,而关闭浏览器后这个session id就消失了,再次链接服务器时也就没法找到原来的session。若是服务器设置的cookie被保存在硬盘上,或者使用某种手段改写浏览器发出的HTTP请求头,把原来的session id发送给服务器,则再次打开浏览器仍然可以打开原来的session.

偏偏是因为关闭浏览器不会致使session被删除,迫使服务器为session设置了一个失效时间,当距离客户端上一次使用session的时间超过这个失效时间时,服务器就能够觉得客户端已经中止了活动,才会把session删除以节省存储空间。

本文转至 http://blog.csdn.net/tobetheender/article/details/52485948