我们在登录某一网站经常记录登录状态,或者访问第三方网站,不知道怎么实现交互的,以下具体分析几种方法,并对他们相互之间进行比较,包括Session、Token、JWT、OAuth2。 先以总结主要点引出细节。
从分类上说,
从应用场景长说,
从具体实现来说,
Session 和 Cookie的区别
安全性: Session 比 Cookie 安全,Session 是存储在服务器端的,Cookie 是存储在客户端的。
存取值的类型不同:Cookie 只支持存字符串数据,想要设置其他类型的数据,需要将其转换成字符串,Session 可以存任意数据类型。
有效期不同: Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能,Session 一般失效时间较短,客户端关闭(默认情况下)或者 Session 超时都会失效。
存储大小不同: 单个 Cookie 保存的数据不能超过 4K,Session 可存储数据远高于 Cookie,但是当访问量过多,会占用过多的服务器资源。
Token和Session
“会话信息”窗口显示当前登录到 Access Manager 的所有用户,并显示每个用户的会话时间。显示的字段包括:
用户 ID。 显示当前登录用户的用户 ID。
剩余时间。 显示需要重新验证之前,用户的该会话所剩余的时间(以分钟为单位)。
最长会话时间。 显示用户在会话过期而必须重新验证以重新获得访问权限之前可以登录的最长时间(以分钟为单位)。
空闲时间 。显示用户处于空闲状态的时间(以分钟为单位)。
最长空闲时间。 显示用户在需要重新验证之前,可以处于空闲状态的最长时间(以分钟为单位)。
时间限制由管理员在“会话管理服务”中定义。
在“用户 ID”字段中输入字符串,然后单击“过滤”可以显示特定的用户会话或用户会话中特定的部分。允许输入通配符。
还可以查看登录源IP地址、登录时间、登出时间等详细信息。
token令牌,构成是:
Token 和 Session 的区别
通过响应体返回给客户端的
,保存在cookie、localstorage等中,
再次请求时不会默认携带
,可以在请求头Authorization携带token;
sessionId是服务端设置在cookie中,客户端每次请求会默认带上它
。
作为身份认证 Token 安全性比 Session 好
,因为每一个请求都有签名还能防止监听以及重放攻击,而 Session 就必须依赖链路层来保障通讯安全了。如果你需要实现有状态的会话,仍然可以增加 Session 来在服务器端保存一些状态。
认证是针对用户,授权是针对 App,
其
目的是让某 App 有权利访问某用户的信息
。token 是唯一的。不可以转移到其它 App上,也不可以转到其它用户上;
Session 只提供一种简单的认证,即只要有此 SessionID ,即认为有此 User 的全部权利
。(所以简单来说:
如果你的用户数据可能需要和第三方共享,或者允许第三方调用 API 接口,用 Token 。如果永远只是自己的网站,自己的 App,用什么就无所谓了
。)
回想下数据链路层?因为为啥说session在链路层上保障安全?
为什么大部分选择Token不用Session?
客户端浏览器只要保存自己的sessionID即可,而服务器却要保存所有用户的Session信息,这对于服务器来说开销较大,而且不利用服务器的扩展。
另外sessionId保存在客户端,容易发起恶意请求,不安全,当然token签名不能被盗,被盗那也不安全,所以设置过期时间不能太长。
cookie/session在单服务器,单域名时比较简单,否则的话,就要考虑如何将客户端的session保存或同步到多个服务器。还要考虑一旦宕机,内存中的这些信息是否会丢失。token因为服务器不保存用户身份,就不存在这个问题,更利于分布式部署
Cookie:保存在浏览器种,有大小限制,有状态;没有特殊限制cookie,客户端每次请求会默认带上它。
Session:保存在服务器中,服务器有资源开销,分布式、跨系统、单点登录、允许第三方调用api接口、用户数据需要与第三方共享等不适合实现;
Token:客户端可以将Token保存到任何地方,无限制,无状态,利于分布式部署。
sessionID 是连接 Cookie 和 Session 的一道桥梁
如果只是自己的简单网站,倾向于使用session。如果系统同时登录用户多,集群服务器多,有单点登录需求,则倾向于使用token。
什么是 JWT
目前最流行的跨域认证解决方案
。
WT (Web Token)
WT包含三个部分: Header头部,Payload负载和Signature签名。由三部分生成token,三部分之间用“.”号做分割。
Header 在Header中通常包含了两部分:type:代表token的类型,这里使用的是JWT类型。 alg:使用的Hash算法,例如HMAC SHA256或RSA。
{ "alg": "HS256", "typ": "JWT" } 这会被经过base64Url编码形成第一部分
Payload token的第二个部分是荷载信息,它包含一些声明Claim(实体的描述,通常是一个User信息,还包括一些其他的元数据) 声明分三类:
JWT 认证流程
Authorization: Bearer
Token 和 JWT 的区别
token包含: uid(用户唯一身份标识)+ timestamp(当前时间戳) + sign(签名)
WT包含:header(头部) + payload(负载 )+ sign(签名)
一般,JWT 并不使用 Cookie,放在请求头 Authorization中,Token存储在Cookie中。
因为JWT不使用 Cookie 的,所以你可以使用任何域名提供你的 API 服务而不需要担心跨域资源共享问题(CORS)
还需要查询数据库获取用户信息,然后验证 Token 是否有效
。
将 Token 和 Payload 加密后存储于客户端
,服务端只需要使用密钥解密进行校验(校验也是 JWT 自己实现的)即可,
不需要查询或者减少查询数据库
,因为 JWT 自包含了用户信息和加密的数据。
用一句话总结最大区别:Token是需要查询数据库,JWT不要查询,直接用秘钥在服务端进行校验。
OAuth
在OAuth2.0中“O”是Open的简称,表示“开放”的意思。Auth表示“授权”的意思,所以连起来OAuth表示“开放授权”的意思,它是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用。用一句话总结来说,OAuth2.0是一种授权协议。
OAuth允许用户授权第三方应用访问他存储在另外服务商里的各种信息数据,而这种授权不需要提供用户名和密码提供给第三方应用
。
eg: 飞书中开发的应用在飞书中免登录
总的来说:OAuth2.0这种授权协议,就是保证第三方应用只有在获得授权之后,才可以进一步访问授权者的数据。
第三方应用先申请
获取一个授权码
,然后再使用该授权码获取令牌,最后使用令牌获取资源;授权码模式是工能最完整、流程最严密的授权模式。它的特点是通过客户端的后台服务器,与服务提供商的认证服务器进行交互。
飞书用的免登录也是OAuth2.0逻辑
function getCode() {
let code = getUrlParam("code");
console.log("code:", code);
if (code) {
getUseInfo(code);
} else {
window.location.href =
"https://open.work.sany.com.cn/open-apis/authen/v1/user_auth_page?app_id=cli_a0b221d078389076&redirect_uri=http%3A%2F%2F222.240.242.218%3A8888%2Fdevice%2F";
授权码code时间特别短,飞书就仅仅设置了1分钟,之前在得到是2分钟。
拿到授权码,我们的服务端会去认证服务器请求数据。
https://server.example.com/oauth/token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=CALLBACK_URL
请求参数解释:
client_id:客户端id,第三方应用在服务提供者平台注册的;
client_secret:授权服务器的秘钥,第三方应用在服务提供者平台注册的;
grant_type:值是AUTHORIZATION_CODE
,表示采用的授权方式是授权码;
code:表示上一步获得的授权码;
redirect_uri:redirect_uri参数是令牌颁发后的回调网址,且必须与A步骤中的该参数值保持一致;
注:client_id参数和client_secret参数用来让 B 确认 A 的身份(client_secret参数是保密的,因此只能在后端发请求)
公司这么多应用平台就可以用OAuth,这样只要登录一个用户就行,其他应用都免登录。
OAuth2.0的授权模式
授权码模式(authorization code)
简化模式(implicit)
密码模式(resource owner password credentials)
客户端模式(client credentials)
具体实现逻辑参考:www.jianshu.com/p/a0905113b…
JWT和OAuth2的区别
功能属性不一样
JWT是一种认证协议,验证用户对资源是否可以访问
OAuth2是一种授权框架,提供了一套详细的授权机制(指导),可以授权第三方应用访问特定资源。
应用场景不一样
JWT是用在前后端分离, 需要简单的对后台API进行保护时使用
OAuth2用在使用第三方账号登录的情况(比如使用weibo, qq, github登录某个app)
OAuth2是一个相对复杂的协议, 有4种授权模式, 其中的access code模式在实现时可以使用jwt生成code
, 也可以不用,它们之间没有必然的联系;OAuth2有client和scope的概念,jwt没有。
很多情况下,在讨论OAuth2的实现时,会把JSON Web Token作为一种认证机制使用
。
我们在登录某一网站经常记录登录状态,或者访问第三方网站,不知道怎么实现交互的,以上具体分析几种方法,并对他们相互之间进行比较,包括Session、Token、JWT、OAuth2。
从分类上说,
Session是一种认证机制
Token、JWT是认证授权机制
OAuth2是授权框架
从应用场景长说,
Session:自己的简单网站;
Token:分布式、跨系统、单点登录、允许第三方调用api接口、用户数据需要与第三方共享等不适合实现。
JWT:场景可以同Token,但是获取验证token的实现逻辑不一样
OAuth2:授权第三方应用、多平台单点登录
从具体实现来说,
Session:基于cookie和sessionId
Token的token: uid(用户唯一身份标识)+ timestamp(当前时间戳) + sign(签名)
JWT的token:header(头部) + payload(负载 )+ sign(签名)
OAuth2:基于授权码code、client_id、client_secret等
cookie不是身份认证方式的一种,session、token都可基于它实现认证。
认证是针对用户,授权是针对App或者网址。