Web技术:Token与Session到底是什么呢

前言

在web中,咱们常常说session,token,cookie。这三个内容,究竟啥区别,为何会有这三个内容呢?这就是咱们今天想要讨论的。ios

故事,美好的开始

洋洋: 琪琪,大家原先的开发 权限是怎么认证的?web

琪琪: 权限?不就是拦截器嘛?经过拦截不一样的url,进行拦截,而后进行校验。redis

洋洋: 那大家用过shiro嘛?进行权限校验的。算法

琪琪: 那个却是没用过,我原先了解是用token作的,而后再造轮子写权限。sql

洋洋: 哦哦那你讲下session与token 是啥?我仍是有点不明白呢,大家当初是怎么设计的?数据库

故事开始了

既然要说 session 与token,顺便了解下cookie?后端

cookie

co哥: 该我出场提问了。第一个问题: 为何要有cookie? 琪琪: 为何要有呢?(小样,居然问我这么简单的问题)。有它不就是为了存储web中的状态信息嘛,方便服务端使用嘛。浏览器

co哥:那cookie 通常是怎么拥有的?客户端能够建立嘛? 琪琪:咱们都说cookie存在于客户端,若是不是篡改的问题,cookie第一次是服务器向客户端发送的安全

co哥:你说的对,顺便再加一个就是咱们的浏览器也会将cookie保存,而且每次请求后也把这些信息发送给服务端哦。bash

琪琪: 恩?那发送的是什么格式呢?(自问自答怎么样?)有什么限制吗?

琪琪: cookie吗? 简单说就是遵循name=value 格式的字符串。还有就是4kB的大小限制,cookie中其余内容就是可选项了。

琪琪: 还有一点就是set-cookie是在header中哦.

顺便提供下主要构成吗,你们能够看下。

name:一个惟一肯定的cookie名称。一般来说cookie的名称是不区分大小写的。

value:存储在cookie中的字符串值。最好为cookie的name和value进行url编码

domain:cookie对于哪一个域是有效的。全部向该域发送的请求中都会包含这个cookie信息。这个值能够包含子域(如:yq.aliyun.com),也能够不包含它(如:.aliyun.com,则对于aliyun.com的全部子域都有效).

path: 表示这个cookie影响到的路径,浏览器跟会根据这项配置,像指定域中匹配的路径发送cookie。

expires:失效时间,表示cookie什么时候应该被删除的时间戳(也就是,什么时候应该中止向服务器发送这个cookie)。若是不设置这个时间戳,浏览器会在页面关闭时即将删除全部cookie;不过也能够本身设置删除时间。这个值是GMT时间格式,若是客户端和服务器端时间不一致,使用expires就会存在误差。

max-age: 与expires做用相同,用来告诉浏览器此cookie多久过时(单位是秒),而不是一个固定的时间点。正常状况下,max-age的优先级高于expires。

HttpOnly: 告知浏览器不容许经过脚本document.cookie去更改这个值,一样这个值在document.cookie中也不可见。但在http请求张仍然会携带这个cookie。注意这个值虽然在脚本中不可获取,但仍然在浏览器安装目录中以文件形式存在。这项设置一般在服务器端设置。

secure: 安全标志,指定后,只有在使用SSL连接时候才能发送到服务器,若是是http连接则不会传递该信息。就算设置了secure 属性也并不表明他人不能看到你机器本地保存的 cookie 信息,因此不要把重要信息放cookie就对了
复制代码

session 你来了?

wa: 既然有了cookie,那为何还出来session了?这是作什么的?

session 生成

浏览器第一次访问服务器的时候,服务器会建立一个session,同时生成惟一的key,则是sessionID。

琪琪: 小黑板来了,我来提问了,第一次访问,那多个浏览器使用同一个帐户信息,服务器不作其余限制,那是否是造成多个session呢?

wa: 固然了,每次访问都会造成一个新的sessionID,那就是session不同了.这样至关于session 都保持此次会话访问的链接。

琪琪:会话访问的链接?那就表明有状态了哦。 那在后端是怎么把session返回给客户端的?

wa: 经过设置cookie的方式返回给客户端哦。固然在后端的时候咱们也能够将session保存到数据库或者redis这些nosql中。

琪琪:咱们经过cookie发送了。但有时候浏览器禁止cookie怎么办?

wa: 这个嘛?我想一想...(你说你问这么多干吗,还得费脑子)。能够经过URL重写的方式发送给服务器哦。

琪琪: 这也对。但还有个问题,若是咱们后台有个服务器部署,属于分布式的,那我再其中一台登陆了,称为A,session也保存到A中,万一下次我访问到另一台服务器B怎么办?B上没有A的session呢。

wa: enenen ? 你问我?我也不知道。

le: 来来,我说下吧。能够这样嘛,既然每一个服务器都有session,那咱们就保存到库里面算了。这样咱们就能互相经过访问过来的cookie 里拿到session信息与库中的进行对比。session 就共享了。

2019-02-13-23-38-44
wa: 是哦,经过数据库或者nosql 进行处理了,但这样不就出现另一个问题,咱们须要保存这些数据,若是数量小点还好说数据量大了这些内容不也就带来性能问题?

le: 嗯呢,因此集群,出来了,因此每次保存这些session信息就是一个负担了。这就是咱们须要在系统设计的时候考虑,状态信息须要保存嘛?

session的终结者,token你选择嘛?

session 是保存了会话的连接信息与咱们须要传输的内容,容量大,还须要保持会话信息,每次同一用户不一样客户端访问我都须要从新创建session,形成冗余信息大。

ff: 这该怎么办呢,真不想保存。

琪琪:这还不简单,那就不保存了,采用token吧?

ff: token? 那是个啥?

琪琪: ennnn,那不是啥。那是一个新技术,被称为令牌的东西。

ff: 那token能验证用户的合法性嘛?

琪琪: ...固然,好比用户登陆了,咱们会把令牌信息,发送给他,包含了一个他的userId,表明他的信息,再访问的时候经过header或者bady带过来就好。

ff: 感受与sessionID没有区别呢? 咦,貌似不用存储session信息到库里面了,还有每次不一样的会话建立新的token,也不影响(单点登陆貌似能够经过token作哦,作过的小伙伴能够尝试下)。好神奇。

琪琪: 是的,是否是感受token比session好多了?

ff: ennnn,但这不是给黑客创造了伪造的 token信息嘛?怎么防止这些信息呢?

琪琪: 这还不简单,对我们返回的token里面数据作一个签名,秘钥别人不知道,这样伪造的token不就通不过咱们的限制了嘛。加密算法能够采用HMAC-SHA256这些算法了etc.

ff :神奇的token啊。这就解决session 这些问题了。

session与token 故事完了吗?

嘿嘿,怎么能结束呢,只说了理论,但还有不少问题没解决呢。就让琪琪一个个提问吧。

wa: 先不提问,我再说几个结论,在提问。。

  • token 是无状态的,后端不须要记录信息,每次请求每次解密就行。
  • session 是有状态的,须要后端每次去检索id的有效性。不一样的session都须要进行保存哦。但让也能够设置单点登陆,减小保存的数据。
  • session与token的问题是空间与时间博弈,为何这么说呢,是由于token不须要保存,直接获取,每次访问都须要进行解密。

好了就先说这几条吧,之后有了在补充。

琪琪:总结了这么多了,那咱们开始提问了。首先,为啥客户端ios与Andriod基本上没见过用session的?

ff: 这个我来回答吧。由于在这些客户端上啊,原生接口都是每一次创建一个会话,这就出问题了,这样会致使登陆功能失效了,登陆每次把信息放到session中,session都不同了,每次登陆都成新的一我的了,这就不ok了。

琪琪:哦哦原来客户端是每次用原生接口都是新创建一个会话,好尴尬的设计。那咱们采用什么方式解决这个问题呢?

ff: 在用户登陆后,重点哦咱们能够经过cookie嘛,咱们在app端也能够是存储cookie的,咱们知道cookie将sessionID保存好,返回给客户端,服务器最后也是经过SessionId来标识的。可是利用token的话,内容咱们能够自定义,而且不用再服务端进行保存。方便咱们处理。

琪琪:那么就是token能够保存到cookie中,若是禁止的话咱们也能够保存到body中每次都请求上或者header中。

总结

恩,token,cookie,session的内容就到这里的,不一样的方案都有各个的区别,固然从这里看我门了解的仍是不不够多,须要继续努力

欢迎你们关注公众号LuckQI.

LuckQI
相关文章
相关标签/搜索