在web中,咱们常常说session,token,cookie。这三个内容,究竟啥区别,为何会有这三个内容呢?这就是咱们今天想要讨论的。ios
洋洋: 琪琪,大家原先的开发 权限是怎么认证的?web
琪琪: 权限?不就是拦截器嘛?经过拦截不一样的url,进行拦截,而后进行校验。redis
洋洋: 那大家用过shiro嘛?进行权限校验的。算法
琪琪: 那个却是没用过,我原先了解是用token作的,而后再造轮子写权限。sql
洋洋: 哦哦那你讲下session与token 是啥?我仍是有点不明白呢,大家当初是怎么设计的?数据库
既然要说 session 与token,顺便了解下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就对了
复制代码
wa: 既然有了cookie,那为何还出来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 就共享了。
le: 嗯呢,因此集群,出来了,因此每次保存这些session信息就是一个负担了。这就是咱们须要在系统设计的时候考虑,状态信息须要保存嘛?
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 这些问题了。
嘿嘿,怎么能结束呢,只说了理论,但还有不少问题没解决呢。就让琪琪一个个提问吧。
wa: 先不提问,我再说几个结论,在提问。。
好了就先说这几条吧,之后有了在补充。
琪琪:总结了这么多了,那咱们开始提问了。首先,为啥客户端ios与Andriod基本上没见过用session的?
ff: 这个我来回答吧。由于在这些客户端上啊,原生接口都是每一次创建一个会话,这就出问题了,这样会致使登陆功能失效了,登陆每次把信息放到session中,session都不同了,每次登陆都成新的一我的了,这就不ok了。
琪琪:哦哦原来客户端是每次用原生接口都是新创建一个会话,好尴尬的设计。那咱们采用什么方式解决这个问题呢?
ff: 在用户登陆后,重点哦咱们能够经过cookie嘛,咱们在app端也能够是存储cookie的,咱们知道cookie将sessionID保存好,返回给客户端,服务器最后也是经过SessionId来标识的。可是利用token的话,内容咱们能够自定义,而且不用再服务端进行保存。方便咱们处理。
琪琪:那么就是token能够保存到cookie中,若是禁止的话咱们也能够保存到body中每次都请求上或者header中。
恩,token,cookie,session的内容就到这里的,不一样的方案都有各个的区别,固然从这里看我门了解的仍是不不够多,须要继续努力
欢迎你们关注公众号LuckQI.