大家leader 可能都不知道的用户鉴权机制的原理

互联网年代,一个网站的用户数,就是这个网站的命脉,那么,这些用户的帐户安全问题很成问题,因而行业大佬们,开始忧国忧民,研究出不少解决当下痛点的解决方案。从最开始的先后端不分离,研究出来的session-cookie,到后来基于前端存储的Token 验证 ,后来网站愈来愈多多了,为了避免老是注册帐号推出来的OAuth权限,以及一个公司项目太多了,为了防止重复登陆开启的单点登陆。html

到这里你就会发现,咱们每一步的鉴权方案,其实就是一个前端的行业成长史,每一种方案,都在特定的历史环境下,解决了一些痛点,而且在行业突飞猛进的状况下,完成了历史使命,而退出舞台。前端

在我看来透彻的了解目前的前端鉴权方案,除了有利于咱们面试找工做。一样的他能帮助你了解前端这个工种,是怎样从一个简单的切图仔一步步成长为工程师的。是有多少前辈在刀耕火种的年代,不畏艰难积累知识,了解过去。开枝散叶,无私奉献,才有了咱们今天的高薪。繁荣git

因而,你开始满怀敬畏,空杯心态,努力学习,乐于助人,积极进取 .........吧啦吧啦吧啦.......github

以上内容纯属扯淡,就到这吧!下面开始正题,本文为某最近整理前端鉴权机制的大体体系留下来的一些笔记,若有帮助请点赞,若有错误请指出,如已了然,请全当乐呵!web

本文大致从时间线,以及解决何种问题,和大体底层原理来阐述前端鉴权的几种经常使用方案。请各位看官批评!面试

session-cookie

首先登场的是session-cookie机制,这是出现时间最先,也是使用最多的鉴权方式(由于如今不少老系统还在维护)。redis

在正式开讲以前咱们先了解一什么叫cookie,什么叫session, 为啥要有这两种产物算法

Session

咱们知道互联网的兴起离不开网络,网络就离不开协议,而在咱们前端中打交道的就是http协议,然而,他好死不死的是个无状态协议,就是在传输过程当中不记录先后端交互的一些状态,在互联网迅猛发展的过程当中,就有了用户的概念,一个网站也不是纯展现为主,因而服务端须要记录用户的状态时,就须要用某种机制来识具体的用户,这个机制就是Session,上述内容可能还有伙伴不太明白,接下来举个例子数据库

典型的场景好比购物车,当你点击下单按钮时,因为HTTP协议无状态,因此并不知道是哪一个用户操做的,因此服务端要为特定的用户建立了特定的Session,用于标识这个用户,而且跟踪用户,这样才知道购物车里面有几本书。这个Session是保存在服务端的,有一个惟一标识。编程

到这里你就会发现其实Session就是一个信息,而且有一个惟一标识,来识别身份

cookie

刚才说到,session是一个信息,这样范围就很广了,他像是一个抽象的概念,而cookie 则是一个真实存在的东西,他是客户端或者浏览器的一种技术,说白了就是一种存储内容的技术,而且会在客户端发起http请求的时候携在http的header中。

ok 说完这二者以后咱们就应该明白了他们二者的区别和联系,接下来就来验证一一下session-cookie 的鉴权机制究竟是怎么样的

image.png

如上图所示,所谓session-cookie模式就是将服务器保存信息,生成一个惟一标识,而后下发给客户端,保存在cookie中,这样每次客户端就能使用这个惟一标识去判断用户的一些状态以及登陆信息,这就是session-cookie的原理。

其实本质很质朴,可是因为互联网的发展,只是简单的生成一个惟一标识很容易被人破解,因而,又开始了折腾之路。

因为最开始的简单生成一个cookie,很容易被人模仿,和伪造,和篡改,这样用户信息就会泄露,因而,引入Hash算法,来验证当前用户身份,防止伪造。

hash算法

哈希(hash)算法又称为散列算法,经过hash算法,能够将任意长度的信息转换成一个固定长度的二进制数据,咱们常常会使用十六进制值来表示转换后的信息。
复制代码

基本原理就是把任意长度的输入,经过Hash算法变成固定长度的输出。这个映射的规则就是对应的Hash算法,而原始数据映射后的二进制串就是哈希值。活动开发中常用的MD5和SHA都是历史悠久的Hash算法。

ok 说了这么多,hash算法有什么特色呢?

  • 从hash值不能够反向推导出原始的数据
  • 输入数据的微小变化会获得彻底不一样的hash值,相同的数据会获得相同的值
  • 哈希算法的执行效率要高效,长的文本也能快速地计算出哈希值
  • hash算法的冲突几率要小

在密码学中,hash算法的做用主要是用于消息摘要和签名,换句话说,它主要用于对整个消息的完整性进行校验。

举个例子,咱们登录掘金的时候都须要输入密码,那么掘金若是明文保存这个密码,那么黑客就很容易窃取你们的密码来登录,特别不安全。因此,他就使用hash算法生成一个密码的签名,数据库保存这个签名值。因为hash算法是不可逆的,那么黑客即使获得这个签名,也丝毫没有用处;由于他反推不出来这个密码。而若是你在网站登录界面上输入你的密码,那么提交请求的时候从新计算一下这个hash值,与网站中储存的原hash值进行比对,若是相同,证实你拥有这个帐户的密码,那么就会容许你登录。银行也是如此,银行是万万不敢保存用户密码的原文的,只会保存密码的hash值而而已。

而在咱们的sessionId 中加入hash算法来生成签名其实和密码的这个例子相似,是为了防止黑客拿到sessionid 可是因为hash算法生成了一个签名,那么若是在访问接口的时候不匹配,那么就能够判断当前用户是伪造的。

Token 验证(jwt)

在了解完了cookie-session 原理以后,咱们发现cookie-session有着不少不足,这时大佬们有开始研究了。这就是后来的token 验证,咱们先来看看cookie-session的不足

  • 服务器有状态,须要要保存全部人的session id ! 若是访问服务器多了, 就得由成千上万,甚至几十万个,压力山大
  • 很是不灵活,若是APP没有cookie并无办法存储,跨域状况下在不作特殊处理的状况下,cookie没法传递

因而大名鼎鼎的tokne模式横空出世,这也是当下全部企业级项目广泛的鉴权方式,那么他有什么特色呢?

  • 支持跨域访问: Cookie是不容许垮域访问的,token支持
  • 无状态: token无状态,session有状态的
  • 去耦: 不须要绑定到一个特定的身份验证方案。Token能够在任何地方生成,只要在你的API被调用的时候, 你可 以进行Token生成调用便可
  • 更适用于移动应用: Cookie不支持手机端访问的
  • 性能: 在网络传输的过程当中,性能更好
  • 基于标准化: 你的API能够采用标准化的 JSON Web Token (JWT). 这个标准已经存在 多个后端库(.NET, Ruby, Java,Python, PHP)和多家公司的支持(如: Firebase,Google, Microsoft)

那么他是怎么工做的呢?

    1. 客户端使⽤用⽤用户名跟密码请求登陆
    1. 服务端收到请求,去验证⽤用户名与密码
    1. 验证成功后,服务端会签发⼀一个令牌(Token),再把这个 Token 发送给客户端
    1. 客户端收到 Token 之后能够把它存储起来,⽐好比放在 Cookie ⾥里里或者 Local Storage⾥里里
    1. 客户端每次向服务端请求资源的时候须要带着服务端签发的 Token
    1. 服务端收到请求,而后去验证客户端请求⾥里里⾯面带着的 Token,若是验证成功,就向客户端返回请求的数据token会有过时时间,客户端登出的时候也会废弃token,可是服务端不不须要任何操做

image.png 到目前为止咱们先来对比一下Token与cookie-session的区别

  • session要求服务端存储信息,而且根据id可以检索,⽽而token不不须要(由于信息就在token中,这样实现了了服务端⽆无状态化)。在⼤大规模系统中,对每一个请求都检索会话信息多是⼀一个复杂和耗时的过程。但另外⼀一⽅方⾯面服务端要经过token来解析⽤用户身份也须要定义好相应的协议(⽐好比JWT)。
  • session⼀通常经过cookie来交互,⽽而token⽅方式更更加灵活,能够是cookie,也能够是header,也能够放在请求的内容中。不不使⽤用cookie能够带来跨域上的便便利利性。
  • token的⽣生成⽅方式更更加多样化,能够由第三⽅方模块来提供。
  • token若被盗⽤用,服务端⽆没法感知,cookie信息存储在⽤用户⾃⼰电脑中,被盗⽤用⻛风险很是小。

明白了工做流程,咱来来一块儿研究下原理,以前咱们说过token鉴权是有标准的好比jwt,那么咱们就来解析jwt原理

JWT( JSON WEB TOKEN)原理理解析

一个 JWT token 是一个字符串,它由三部分组成,令牌头、载荷(payload)与签名(Signature)
复制代码

那么他长生么样呢?

image.png

如上图所示,就长这个样子,三个部分直接用.分隔,接下来咱们一个个解析

令牌头(header)

header典型的由两部分组成:token的类型(“JWT”)和算法名称(好比:HMAC SHA256或者RSA等等)。

{
  "alg": "HS256",
  "typ": "JWT"
}
复制代码

而后用 Base64Url 编码获得头部,即 ewogICJhbGciOiAiSFMyNTYiLAogICJ0eXAiOiAiSldUIgp9。

JWT签名算法中,通常有两个选择,一个采用HS256,另一个就是采用RS256。 签名其实是一个加密的过程,生成一段标识(也是JWT的一部分)做为接收方验证信息是否被篡改的依据。

RS256 (采用SHA-256 的 RSA 签名) 是一种非对称算法, 它使用公共/私钥对: 标识提供方采用私钥生成签名, JWT 的使用方获取公钥以验证签名。因为公钥 (与私钥相比) 不须要保护, 所以大多数标识提供方使其易于使用方获取和使用 (一般经过一个元数据URL)。 另外一方面, HS256 (带有 SHA-256 的 HMAC 是一种对称算法, 双方之间仅共享一个 密钥。因为使用相同的密钥生成签名和验证签名, 所以必须注意确保密钥不被泄密。

在开发应用的时候启用JWT,使用RS256更加安全,你能够控制谁能使用什么类型的密钥。另外,若是你没法控制客户端,没法作到密钥的彻底保密,RS256会是个更佳的选择,JWT的使用方只须要知道公钥。

因为公钥一般能够从元数据URL节点得到,所以能够对客户端进行进行编程以自动检索公钥。若是采用这种方式,从服务器上直接下载公钥信息,能够有效的减小配置信息。

载荷(Payload)

载荷中放置了 token 的一些基本信息,以帮助接受它的服务器来理解这个 token。同时还能够包含一些自定义的信息,用户信息交换。

载荷的属性也分三类:

  • 预约义(Registered)
  • 公有(public)
  • 私有(private)

咱们先来看预约义,这里面的前 7 个字段都是由官方所定义的,也就是预约义(Registered claims)的,并不都是必需的。

{
  "sub": "1", //主题
  "iss": "http://localhost:8000/auth/login",//该JWT的签发者
  "iat": 1451888119,//在何时签发的
  "exp": 1454516119,// 何时过时,这里是一个Unix时间戳
  "nbf": 1451888119,//生效时间,在此以前是无效的
  "jti": "37c107e4609ddbcc9c096ea5ee76c667",//编号
  "aud": "dev"//受众

复制代码

公有的声明

公共的声明能够添加任何的信息,通常添加用户的相关信息或其余业务须要的必要信息.但不建议添加敏感信息,由于该部分在客户端可解密.

私有声明

{
"sub":"1234567890",// 预约义
"name":"hore_brother",
"admin":true
}
复制代码

私有声明是提供者和消费者所共同定义的声明,通常不建议存放敏感信息,由于base64是对称解密的,意味着该部分信息能够归类为明文信息。

这个指的就是自定义的声明。好比前面那个结构举例中的admin和name都属于自定的私有声明。这些声明跟JWT标准规定的声明区别在于:JWT规定的声明,JWT的接收方在拿到JWT以后,都知道怎么对这些标准的声明进行验证(还不知道是否可以验证);而私有声明不会验证,除非明确告诉接收方要对这些声明进行验证以及规则才行。

将上面的 json 进行 Base64Url 编码获得载荷,,即 CnsKICAic3ViIjogIjEiLAogICJpc3MiOiAiaHR0cDovL2xvY2FsaG9zdDo4MDAwL2F1dGgvbG9naW4iLAogICJpYXQiOiAxNDUxODg4MTE5LAogICJleHAiOiAxNDU0NTE2MTE5LAogICJuYmYiOiAxNDUxODg4MTE5LAogICJqdGkiOiAiMzdjMTA3ZTQ2MDlkZGJjYzljMDk2ZWE1ZWU3NmM2NjciLAogICJhdWQiOiAiZGV2Igp9。

注意:base64是一种编码,它是能够被翻译回原来的样子来的。它并非一种加密过程。

签名(Signature)

jwt的签名信息由三部分组成:header (base64后的),payload (base64后的),secret(秘钥)
复制代码

拿到这三部分以后,使用加密算法加密以后编码生成最后的签名部分。若是以 HMACSHA256 加密,

HMACSHA256(
    base64UrlEncode(header) + "." +
    base64UrlEncode(payload),
    secret
)
复制代码

你是否是以为很麻烦,其实社区已经有封装的库了。

// jsonwebtoken.js
const jsonwebtoken = require('jsonwebtoken')
const secret = '12345678'
const opt = {
  secret: 'jwt_secret',
key: 'user' }
const user = {
  username: 'abc',
  password: '111111'
}
const token = jsonwebtoken.sign({
data: user,
// 设置 token 过时时间
exp: Math.floor(Date.now() / 1000) + (60 * 60),
}, secret)
console.log('⽣生成token:' + token)
// ⽣生成 token:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InVzZXJuYW1lIjoiYWJjIiw icGFzc3dvcmQiOiIxMTExMTEifSwiZXhwIjoxNTQ2OTQyMzk1LCJpYXQiOjE1NDY5Mzg3OTV9.VPBC QgLB7XPBq3RdHK9WQMkPp3dw65JzEKm_LZZjP9Y
复制代码

使用上述库就能经过简单的api实现token的生成 而且因为签名部分的加密秘钥在服务端,即实现了在客户端携带信息,而且防止篡改。有的人又会问了,他为啥能防篡改呢?

HMAC 算法是不可逆算法,相似 MD5 和 hash ,但多一个密钥,密钥(即上面的 secret)由服务端持有,客户端把 token 发给服务端后,服务端能够把其中的头部和载荷再加上事先共享的 secret 再进行一次 HMAC 加密,获得的结果和 token 的第三段进行对比,若是同样则代表数据没有被篡改。
复制代码

OAuth(开放受权)

OAuth是在如今的互联网中的使用很是多,举个例子,咱们登录一个网站,你会发现网站上有qq登录,微信登陆,github 登陆,谷歌登陆等,其实就是OAuth开放受权。

三⽅登⼊主要基于OAuth 2.0。OAuth协议为⽤用户资源的受权提供了⼀个安全的、开放⽽⼜ 简易的标准。与以往的受权⽅式不一样之处是OAuth的受权不会使第三方触及到⽤户的账号信息 (如⽤用户名与密码),即第三⽅方⽆无需使⽤户的⽤户名与密码就能够申请得到该⽤户资源的受权, 所以OAuth是安全的。
复制代码

了解以后,咱们就来简述一下他的原理。因为在咱们平常开发中,每一个平台的对接方式都不同,咱们就以github为例。大体去还原一下想要实现OAuth受权登陆,须要的操做流程,在这里只是简述,如想深刻了解,请去github开发者中心。

假设我有一个网站,而且有用户体系,每一个用户须要有一个帐号,此时,有个新来的用户,想要在当前的帖子上留言,可是他有不想注册帐号而且还想留言 此时怎么办呢? 这是你会发现,不少大型的网站,他已经注册了。好比github,而且github提供了一套鉴权机制让你能这个当前网站能访问到github的用户信息,如此一来,你就能访问就能达到共赢局面,用户既省去了注册的繁琐步骤,你又留住了一个用户,在互联网慢慢的发展中这套鉴权机制就叫作OAuth

接下来咱们来开始一步步揭露他的原理步骤,其实,所谓的OAuth鉴权他的本质就是两个协商的过程,从而肯定网站以及用户的一一对应关系,而且获取用户的意向(赞成仍是不一样意)

  • 网站和 Github 之间的协商
  • 用户和 Github 之间的协商

再根据协商结果去作进一步操做,从而肯定访问权限。

咱们首先须要知道的是。即便用户刚登陆过 github,个人网站也不能随便拿到用户消息,这显然是侵犯用户隐私的,是不安全。因此,咱们必须去进行第一步的协商

网站和 Github 之间的协商

像github这种世界级别的网站,他对受权有着严格的权限分类,好比读取仓库信息的权限、写入仓库的权限、读取用户信息的权限、修改用户信息的权限等等。若是我想获取用户的信息,Github 会要求我,先在它的平台上注册一个应用,在申请的时候标明须要获取用户信息的哪些权限,用多少就申请多少,而且在申请的时候填写你的网站域名,Github 只容许在这个域名中获取用户信息。

此时,若是我若是填了申请,而且审批经过,那么我算是入了github的白名单了,github会给我发两个门票,一张门票叫作 Client Id,另外一张门票叫作 Client Secret。

到这里,第一步就算踏出去了

用户和 Github 之间的协商

用户进入个人网站,点击 github 登陆按钮的时候,个人网站会把上面拿到的 Client Id 交给用户,让他进入到 Github 的受权页面,Github 看到了用户手中的门票,就知道这是个人网站让他过来的,由于一个网站对应一个Client Id,因而它就把个人网站想要获取的权限摆出来,并询问用户是否容许我获取这些权限。此时,就是最关键的一步,获取用户受权,防止侵犯隐私。

在代码上表示其实就是,我去请求一个登陆地址,而后带上一个令牌和成功以后的回调地址

// 用户登陆 github,协商
GET https://github.com/login/oauth/authorize

// 协商凭证
params = {
  client_id: "xxxx",
  redirect_uri: "http://my-website.com"
}
复制代码

若是用户以为个人网站要的权限太多,或者压根就不想我知道他这些信息,选择了拒绝的话,整个 OAuth 2.0 的认证就结束了,认证也以失败了结。若是用户以为 OK,在受权页面点击了确认受权后,页面会跳转到我预先设定的 redirect_uri 并附带一个盖了章的门票 code。

// 协商成功后带着盖了章的 code
Location: http://my-website.com?code=xxx
复制代码

这个时候,用户和 Github 之间的协商就已经完成,Github 也会在本身的系统中记录此次协商,表示该用户已经容许在个人网站访问上直接操做和使用他的部分资源。

执行上面两步以后,鉴权的主体已经完成,剩下的咱们只须要拿着code码去获取github

去github验证拿到最终统统行证

第二步中,咱们已经拿到了盖过章的门票 code,但这个 code 只能代表,用户容许个人网站从 github 上获取该用户的数据,若是我直接拿这个 code 去 github 访问数据必定会被拒绝,由于任何人均可以持有 code,github 并不知道 code 持有方就是我本人。

还记得以前申请应用的时候 github 给个人两张门票么,Client Id 在上一步中已经用过了,接下来轮到另外一张门票 Client Secret。

如此一来,双证齐全,就能知道当前的这个受权用户是从我这个网站出来的。因而,就会给你发一个最终通行证,也就是access_token,模拟代码以下

// 网站和 github 之间的协商
POST https://github.com/login/oauth/access_token

// 协商凭证包括 github 给用户盖的章和 github 发给个人门票
params = {
  code: "xxx",
  client_id: "xxx",
  client_secret: "xxx",
  redirect_uri: "http://my-website.com"
}
复制代码
// 拿到最后的通行证
response = {
  access_token: "e72e16c7e42f292c6912e7710c838347ae178b4a"
  scope: "user,gist"
  token_type: "bearer",
  refresh_token: "xxxx"
}
复制代码

从github获取用户信息在个人网站使用

上一步 github 已经把最后的通行证 access_token 给我了,经过 github 提供的 API 加通行证就可以访问用户的信息了,能获取用户的哪些权限在 response 中也给了明确的说明,scope 为 user 和 gist,也就是只能获取 user 组和 gist 组两个小组的权限,user 组中就包含了用户的名字和邮箱等信息了。

// 访问用户数据
GET //api.github.com/user?access_token=e72e16c7e42f292c6912e7710c838347ae178b4a
复制代码
// 告诉我用户的名字和邮箱
response = {
  username: "好学习吧",
  email: "8888888.abcd@gmail.com"
}
复制代码

到此为止简单的 OAuth登陆认证就到此结束

单点登陆

所谓单点登陆全称叫作:Single Sign On(简称SSO),那究竟什么是单点登陆呢?

在最初的互联网系咱们就是单系统,全部的功能都在同一个系统上。

image.png

后来,咱们为了合理利用资源和下降耦合性,因而把单系统拆分红多个子系统,

image.png

而此时,问题来了,我多个系统之间是不通讯的,那么如何去获取用户的登陆状态呢?好比:淘宝和天猫是两个独立的系统,咱们想要保证两个系统的登陆状态一致,用户信息同步。就会用到单点登陆。

单点登陆简单的说就是在多个系统中,用户只需一次登陆,各个系统便可感知该用户已经登陆

知道了什么是单点登陆之后,他的原理其实很简单,而咱们的实现方式其实看起来也很简单,就是不管使用什么鉴权模式,只须要让多个系统之间的认证信息互通便可。可是咱们却须要解决如下问题。

  • Session不共享问题
  • Cookie跨域的问题
  • 须要单独开一个认证服务器(csa)

接下来我么一个个解决

Session不共享问题

因为多系统之间Session不共享,那么此时就必须有一个公共的地方去存储当前的这个session,如此一来,答案就能够呼之欲出了好比,开一个公共的Redis,或者登陆功能单独抽取出来,作成一个子系统等

Cookie跨域的问题

上面咱们解决了Session不能共享的问题,但其实还有另外一个问题。Cookie是不能跨域的,其实也就是浏览器同源策略的限制。那么解决方案,其实也相对清晰。好比:绕开同源策略。两个网站使用同一个一级域名、或者强制推送cookie 将Token保存在SessionStroage中 在请求的时候携带上等

须要单独开一个认证服务器

第三个问题,实际上是当前的的一个最佳实践,有着一个成熟的解决方案,叫作CAS (Central Authentication Service)

以下图就是他的整体原理图

image.png

接下来我么 来一步步解析

首先模拟了三个服务,分别是CAS、系统A、系统B,它们分别部署在cas.com,systemA.com和systemB.com;CAS这个服务用来管理SSO的会话;系统A和系统B表明着实际的业务系统。我从五个场景分别来讲明这个SSO方案的实现细节。下面先来看第一个。

场景一:用户发起对业务系统的第一次访问,假设他第一次访问的是系统A的some/page这个页面,它最终成功访问到这个页面的过程是:

image.png

在当前第一个场景中,他的第一个场景在于

  • 它用到了两个cookie(jwt和sid)和三次重定向来完成会话的建立和会话的传递;

  • jwt的cookie是写在systemA.com这个域下的,因此每次重定向到systemA.com的时候,jwt这个cookie只要有就会带过去;

  • sid的cookie是写在cas.com这个域下的,因此每次重定向到cas.com的时候,sid这个cookie只要有就会带过去;

  • 在验证jwt的时候,如何知道当前用户已经建立了sso的会话?由于jwt的payload里面存储了以前建立的sso 会话的session id,因此当cas拿到jwt,就至关于拿到了session id,而后用这个session id去判断有没有的对应的session对象便可。

  • CAS服务里面的session属于服务端建立的对象,因此要考虑session id惟一性以及session共享(假如CAS采用集群部署的话)的问题。session id的惟一性能够经过用户名密码加随机数而后用hash算法如md5简单处理;session共享,能够用memcached或者redis这种专门的支持集群部署的缓存服务器管理session来处理。

  • 因为服务端session具备生命周期的特色,到期需自动销毁,因此不要本身去写session的管理,省得引起其它问题,到github里找开源的缓存管理中间件来处理便可。存储session对象的时候,只要用session id做为key,session对象自己做为value,存入缓存便可。session对象里面除了session id,还能够存放登陆以后获取的用户信息等业务数据,方便业务系统调用的时候,从session里面返回会话数据。

场景二:用户登陆以后,继续访问系统A的其它页面,如some/page2,它的处理过程是:

image.png

从这一步能够看出,即便登陆以后,也要每次跟CAS校验jwt的有效性以及会话的有效性,其实jwt的有效性也能够放在业务系统里面处理的,可是会话的有效性就必须到CAS那边才能完成了。当CAS拿到jwt里面的session id以后,就能到session 缓存服务器里面去验证该session id对应的session对象是否存在,不存在,就说明会话已经销毁了(退出)。

场景三:用户登陆了系统A以后,再去访问其余系统如系统B的资源,好比系统B的some/page,它最终能访问到系统B的some/page的流程是:

image.png

这个过程的关键在于第一次重定向的时候,它会把sid这个cookie带回给CAS服务器,因此CAS服务器可以判断出会话是否已经创建,若是已经创建就跳过登陆页的逻辑。

场景四:用户继续访问系统B的其它资源,如系统B的some/page2:

image.png

场景五:退出登陆,假如它从系统B发起退出,最终的流程是:

image.png

最重要的是要清除sid的cookie,jwt的cookie可能业务系统都有建立,因此不可能在退出的时候还挨个去清除那些系统的cookie,只要sid一清除,那么即便那些jwt的cookie在下次访问的时候还会被传递到业务系统的服务端,因为jwt里面的sid已经无效,因此最后仍是会被重定向到CAS登陆页进行处理。

到此为止,sso 单点登陆基本结束了,咱们只作了解便可,由于大部分业务中基本用不上,咱们到目前为止作的单点登陆就是携带token跳转,虽然不安全,可是能快速应用。在面对快速业务开发的咱们。是个最优选择

最后

首先感谢巨人

OAuth 受权的工做原理是怎样的?足够安全吗? 看图理解JWT如何用于单点登陆

断断续续数日,终于将基本的用户鉴权机制的原理整理完成,在我整理完而且本身造成本身的知识体系以后分享出来,但愿对你们有帮助!

相关文章
相关标签/搜索