androidapptoken过期退出登录_Cookie、Session和Token Session
服务器只有⼀台,客户端却有千千万。怎么能够让服务器知道当前请求服务的是哪台客户端呢?我们举个⽣活中的例⼦:
你去图书馆(服务端)借书(请求服务)。先得办卡(登录获取session_id)吧,放兜⾥(cookie)。去刷卡处刷卡看看卡是不是伪造的,看看卡⾥的信息和数据库⽐对下看看有没有过期等等(检查session_id是否被篡改,是否失效根据session_id查询下内存或者数据库(通常是内存数据库)⾥对应的有没有过期)。过期不给进重新办卡(重新登录认证),没过期就给进(返回你请求的结果)
所以咯流程就是这样⼦:
当 client通过⽤户名密码请求server并通过⾝份认证后,server就会⽣成⾝份认证相关的 session 数据,并且保存在内存或者内存数据库。并将对应的 sesssion_id返回给client,client会把保存session_id(可以加密签名下防⽌篡改)在cookie。此后client的所有请求都会附带该session_id(毕竟默认会把cookie传给server),以确定server是否存在对应的session数据以及检验登录状态,权限啦巴拉巴拉……如果通过校验就该⼲嘛⼲嘛,否则重新登录咯。
前端退出的话就清cookie。后端强制前端重新认证的话就清除或者修改session。
Session是对于服务端来说的,客户端是没有Session⼀说的。Session是服务器在和客户端建⽴连接时添加客户端连接标志,最终会在服务器软件(Apache、Tomcat、JBoss)转化为⼀个临时Cookie发送给给客户端,当客户端第⼀请求时服务器会检查是否携带了这个Session(临时Cookie),如果没有则会添加Session,如果有就拿出这个Session来做相关操作。
在这⾥引⽤别⼈家的⼀个⼩故事来加深印象:
在说session是啥之前,我们先来说说为什么会出现session会话,它出现的机理是什么? 我们知道,我们⽤浏览器打开⼀个⽹页,⽤到的是HTTP协议,了解计算机的应该都知道这个协议,它是⽆状态的,什么是⽆状态呢?就是说这⼀次请求和上⼀次请求是没有任何关系的,互不认识的,没有关联的。但是这种⽆状态的的好处是快速。所以就会带来⼀个问题就是,我希望⼏个请求的页⾯要有关联,⽐如:我在www.a/login.php⾥⾯登陆了,我在www.a/index.php 也希望是登陆状态,但是,这是2个不同的页⾯,也就是2个不同的HTTP请求,这2个HTTP请求是⽆状态的,也就是⽆关联的,所以⽆法单纯的在index.php中读取到它在login.php中已经登陆了! 那咋搞呢?我不可能这2个页⾯我都去登陆⼀遍吧。或者⽤笨⽅法这2个页⾯都去查询数据库,如果有登陆状态,就判断是登陆的了。这种查询数据库的⽅案虽然可⾏,但是每次都要去查询数据库不是个事,会造成数据库的压⼒。所以正是这种诉求,这个时候,⼀个新的客户端存储数据⽅式出现了:cookie。cookie是把少量的信息存储在⽤户⾃⼰的电脑上,它在⼀个域名下是⼀个全局的,只要设置它的存储路径在域名www.
a下 ,那么当⽤户⽤浏览器访问时,php就可以从这个域名的任意页⾯读取cookie中的信息。所以就很好的解决了我在www.a/login.php页⾯登陆了,我也可以在www.a/index.php获取到这个登陆信息了。同时⼜不⽤反复去查询数据库。虽然这种⽅案很不错,也很快速⽅便,但是由于cookie 是存在⽤户端,⽽且它本⾝存储的尺⼨⼤⼩也有限,最关键是⽤户可以是可见的,并可以随意的修改,很不安全。那如何⼜要安全,⼜可以⽅便的全局读取信息呢?于是,这个时候,⼀种新的存储会话机制:session 诞⽣了。 Session 就是在⼀次会话中解决2次HTTP的请求的关联,让它们产⽣联系,让2两个页⾯都能读取到个这个全局的session信息。session信息存在于服务器端,所以也就很好的解决了安全问题
Token :
token是⽤户⾝份的验证⽅式,我们通常叫它:令牌。最简单的token组成:uid(⽤户唯⼀的⾝份标识)、time(当前时间的时间戳)、sign(签名,由token的前⼏位+盐以哈希算法压缩成⼀定长的⼗六进制字符串,可以防⽌恶意第三⽅拼接token请求服务器)。还可以把不变的参数也放进token,避免多次查库。
应⽤场景:
A:当⽤户⾸次登录成功(注册也是⼀种可以适⽤的场景)之后, 服务器端就会⽣成⼀个 token 值,这个值,会在服务器保存token值(保存在数据库中),再将这个token值返回给客户端.
B:客户端拿到 token 值之后,进⾏本地保存。(SP存储是⼤家能够⽐较⽀持和易于理解操作的存储)
C:当客户端再次发送⽹络请求(⼀般不是登录请求)的时候,就会将这个 token 值附带到参数中发送给服务器.
D:服务器接收到客户端的请求之后,会取出token值与保存在本地(数据库)中的token值做对⽐
对⽐⼀:如果两个 token 值相同, 说明⽤户登录成功过!当前⽤户处于登录状态!
对⽐⼆:如果没有这个 token 值, 则说明没有登录成功.
对⽐三:如果 token 值不同: 说明原来的登录信息已经失效,让⽤户重新登录.
Cookie和Session的区别:
1、cookie数据存放在客户的浏览器上,session数据放在服务器上。
2、cookie不是很安全,别⼈可以分析存放在本地的cookie并进⾏cookie欺骗,考虑到安全应当使⽤session。
3、session会在⼀定时间内保存在服务器上。当访问增多,会⽐较占⽤你服务器的性能,考虑到减轻
服务器性能⽅⾯,应当使⽤cookie。
4、单个cookie保存的数据不能超过4K,很多浏览器都限制⼀个站点最多保存20个cookie。
5、所以个⼈建议:
将登陆信息等重要信息存放为session
其他信息如果需要保留,可以放在cookie中
Token 和 Session 的区别:
session和 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,⽤什么就⽆所谓了。
token就是令牌,⽐如你授权(登录)⼀个程序时,他就是个依据,判断你是否已经授权该软件;cookie就是写在客户端的⼀个txt⽂件,⾥⾯包括你登录信息之类的,这样你下次在登录某个⽹站,就会⾃动调⽤cookie⾃动登录⽤户名;session和cookie差不多,只是session是写在服务器端的⽂件,也需要在客户端写⼊cookie⽂件,但是⽂件⾥是你的浏览器编号.Session的状态是存储在服务器端,客户端只有session id;⽽Token的状态是存储在客户端。
session如何设置和读取
JWT
这⾥就不介绍jwt的三部分组成、由什么组成、怎么⽣成加密了。
⽇常的举个⽣活中的例⼦吧:
你去游乐园(服务端)玩耍(请求服务)。先得买门票(登录获取token)吧,放兜⾥(cookie、header……)。去检票⼝检票看看票有没有过期(检查token是否失效)。过期不给进重新买票(重新登录认证),没过期就给进(返回你请求的结果)
有没有觉得和Session有什么不⼀样?server不⽤存储信息了。⼀切都存在客户端。个⼈觉得这就是最⼤的不同。
这⾥⼤致列下俩者区别,⼀些⽐如JWT更简单、APP对⽀持不易的⼀些已经解决或者细究觉得很扯的或者⼤同⼩异的不在此列
Session JWT
安全性得考虑CSRF攻击
存储需要俩端都存储
Session JWT
可控性服务端可随时修改权限….
Json Web Token(JWT)
JWT 是⼀个开放标准(RFC 7519),它定义了⼀种⽤于简洁,⾃包含的⽤于通信双⽅之间以 JSON 对象的形式安全传递信息的⽅法。JWT 可以使⽤ HMAC 算法或者是 RSA 的公钥密钥对进⾏签名。它具备两个特点:
简洁(Compact)
可以通过URL, POST 参数或者在 HTTP header 发送,因为数据量⼩,传输速度快
⾃包含(Self-contained)
负载中包含了所有⽤户所需要的信息,避免了多次查询数据库
什么时候你应该⽤JSON Web Tokens
下列场景中使⽤JSON Web Token是很有⽤的:
Authorization (授权) : 这是使⽤JWT的最常见场景。⼀旦⽤户登录,后续每个请求都将包含JWT,允许⽤户访问该令牌允许的路由、服务和资源。单点登录是现在⼴泛使⽤的JWT的⼀个特性,因为它的开销很⼩,并且可以轻松地跨域使⽤。
Information Exchange (信息交换) : 对于安全的在各⽅之间传输信息⽽⾔,JSON Web Tokens⽆疑是⼀种很好的⽅式。因为JWTs 可以被签名,例如,⽤公钥/私钥对,你可以确定发送⼈就是它们所说的那个⼈。另外,由于签名是使⽤头和有效负载计算的,您还可以验证内容没有被篡改。
JSON Web Token的结构是什么样的
JSON Web Token由三部分组成,它们之间⽤圆点(.)连接。这三部分分别是:
Header
Payload
Signature
因此,⼀个典型的JWT看起来是这个样⼦的:
看⼀张官⽹的图就明⽩了:
JWT 组成
Header 头部
头部包含了两部分,token 类型和采⽤的加密算法
{ "alg": "HS256", "typ": "JWT" }
它会使⽤ Base64 编码组成 JWT 结构的第⼀部分,如果你使⽤Node.js,可以⽤Node.js的包base64url来得到这个字符串。
Base64是⼀种编码,也就是说,它是可以被翻译回原来的样⼦来的。它并不是⼀种加密过程。
Payload 负载
这部分就是我们存放信息的地⽅了,你可以把⽤户 ID 等信息放在这⾥,JWT 规范⾥⾯对这部分有进⾏了⽐较详细的介绍,常⽤的由 iss(签发者),exp(过期时间),sub(⾯向的⽤户),aud(接收⽅),iat(签发时间)。
{ "iss": "lion1ou JWT", "iat": 1441593502, "exp": 1441594722, "aud": "ample", "sub": "lion1ou@163" }
同样的,它会使⽤ Base64 编码组成 JWT 结构的第⼆部分
Signature 签名
前⾯两部分都是使⽤ Base64 进⾏编码的,即前端可以解开知道⾥⾯的信息。Signature 需要使⽤编码后的 header 和 payload 以及我们提供的⼀个密钥,然后使⽤ header 中指定的签名算法(HS256)进⾏签名。签名的作⽤是保证 JWT 没有被篡改过。
三个部分通过.连接在⼀起就是我们的 JWT 了,它可能长这个样⼦,长度貌似和你的加密算法和私钥有关系。
其实到这⼀步可能就有⼈会想了,HTTP 请求总会带上 token,这样这个 token 传来传去占⽤不必要的带宽啊。如果你这么想了,那你可以去了解下 HTTP2,HTTP2 对头部进⾏了压缩,相信也解决了这个问题。
签名的⽬的
最后⼀步签名的过程,实际上是对头部以及负载内容进⾏签名,防⽌内容被窜改。如果有⼈对头部以及负载的内容解码之后进⾏修改,再进⾏编码,最后加上之前的签名组合形成新的JWT的话,那么服务器端会判断出新的头部和负载形成的签名和JWT附带上的签名是不⼀样的。如果要对新的头部和负载进⾏签名,在不知道服务器加密时⽤的密钥的话,得出来的签名也是不⼀样的。
信息暴露
在这⾥⼤家⼀定会问⼀个问题:Base64是⼀种编码,是可逆的,那么我的信息不就被暴露了吗?
是的。所以,在JWT中,不应该在负载⾥⾯加⼊任何敏感的数据。在上⾯的例⼦中,我们传输的是⽤户的User ID。这个值实际上不是什么敏感内容,⼀般情况下被知道也是安全的。但是像密码这样的内容就不能被放在JWT中了。如果将⽤户的密码放在了JWT中,那么怀有恶意的第三⽅通过Base64解码就能很快地知道你的密码了。
因此JWT适合⽤于向Web应⽤传递⼀些⾮敏感信息。JWT还经常⽤于设计⽤户认证和授权系统,甚⾄实现Web应⽤的单点登录。JSON Web Tokens是如何⼯作的
1. 应⽤(或者客户端)想授权服务器请求授权。例如,如果⽤授权码流程的话,就是/oauth/authorize
2. 当授权被许可以后,授权服务器返回⼀个access token给应⽤
3. 应⽤使⽤access token访问受保护的资源(⽐如:API)
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论