系统设计:二维码扫码登录设计
By 王帅真
Summary
## Key takeaways - **二维码本质是带ID的URL**: 二维码最终解析出来就是一个字符串,通常是一个URL,包含二维码ID如B站的qr code key。可以用草料二维码解码器验证,微信和B站二维码均如此。 [06:04], [06:53] - **登录核心:标识+证明身份**: 任何登录方式都离不开告诉系统我是谁(唯一标识如账号手机号)和证明我是谁(密码验证码)。二维码登录同样遵循此原则,用移动端token证明身份。 [03:04], [03:48] - **二维码状态机五状态**: 二维码状态包括待扫码、待确认、验证成功、验证失败、已失效,由PC生成、移动扫码、确认等动作触发流转。无论待扫码或待确认,未登录均会过期失效。 [07:17], [09:13] - **服务端用Redis存二维码ID**: 服务端生成带有效期的二维码ID,用Redis以二维码ID为key存储用户信息和设备信息,利用expire time实现过期。B站实际未绑定设备ID也能生成。 [10:44], [11:05] - **二次确认用临时token**: 扫码后服务端返回临时token给移动端,用于二次确认,提升安全性,结合二维码ID和移动端token再请求服务端校验,避免token被劫持。PC端轮询状态直到登录成功。 [14:55], [16:27] - **B站实际四个关键接口**: PC端:生成二维码ID接口、状态轮询接口;移动端:扫码请求临时token接口、二次确认接口。抓包可见generate返回qrcode key,轮询返回status如未扫码、已失效。 [20:14], [23:15]
Topics Covered
- 登录认证双核心:标识与证明
- 二维码本质为带有效期code
- 二维码状态机四状态流转
- 移动端token证明身份关键
- 轮询长连WebSocket状态同步
Full Transcript
Hello 大家好 这里是王帅真 这一期视频呢 呃给大家来讲一下二维码扫码登录的一个设计 前面的话 我们其实都是在讲 那个微信朋友圈的系统设计嘛 因为从数据反馈上来看的话 嗯可能没有预期的那那样 所以微信的那个系列我就暂时先搁置了
就让子弹飞一会儿 如果后续有更多反馈之后 我再去做下一期视频 那这一期的话我们就按照那个投票结果的 下一个就是二维码扫码登录的设计 看视频的各位应该都用过二维码扫码登录啊 如果你没呃 就是说你没有使用过也没有关系 或者说嗯你对那个流程就没有仔细观察过 也没有关系
我们现在可以到场外 我以B站为例给大家来整体示范一下 就这里面最关键的是你的一个流程 就二维码 它怎么从出现二维码到登录进去的状态 就要关注里面的每一个角色和流程 好的啊 我们现在来到场外 然后给大家过一下
整个B站二维码登录的一个流程 首先就是呃web端 我们点击这个登录啊 登录之后它弹出这个页面 它就会在这边生成一个扫描二维码 登录的一个二维码 然后我这边手机打开打开这个 然后我去扫它 那扫它之后呢
这边就会出现扫码成功 请在手机上确认啊 但他没有马上登进去 它其实是有一个二次确认的需要 我在这边点了确认登录之后呢 然后他这边显示登录它才会真正的登录进去 那如果说我不登录了的话 就我一直把二维码放在这边
它就会进入一个过期的状态 这时候我们需要去重新刷新它 它才会出来呃 一个新的嘛 OK刚刚演示的是B站的扫码登录的一个流程 那如果说我们平时用的比较多的微信来说的话 那其实它的流程也是一样的 你你可以自己去试一下 也是这么一个流程 而且甚至大部分的网站大差不差
应该都是长这样的 他觉得他们之间可以是有一些共性的嘛 那我们就可以把这些共性抽出来讨论 那我们思考一下二维码 它有嗯怎么说呢 就是说它有哪一些关键点呢 我们可以先写一下这一期的主题 二维码扫码登录这个东西 它的一个核心核心在哪里
在于登录它的本质还是一个登录方式 本质还是一个登录认证方式 那既然我都讲到了认证 那我我们我们就先回想一下传统的登录模式 有什么账号密码登录 手机号加一个验证码登录 或者说你邮箱加密码或者邮箱加验证码好 或者手机号加密码
这是几个比较常常见的 现在还在还在用的一些登录方式吗 无论说你是什么样的方式 它其实都离不开两个点 就我这边可以列一下 第一个是告诉系统我是谁 还有一个是向系统证明我是谁 这个东西它相对应的
它相对应的就是比如说我们说的啊 账号或者说手机号或者邮箱 然后我说你说的什么用户名 就是user user name啊 也可以就是说它是一个有唯一标识的 只要他能保证能识别到你这个人身上啊 那就OK唯一标识 还有一个是向系统证明我是谁啊
那这个类比我类比一下 就比如说密码这些就是最常见的嘛 就是手机给你发个码 邮箱给你发个码 或者你自己去输密码 都可以用来向系统证明你是你 这是一个登录认证方式 我们现在引入了一个新的东西叫做二维码 二维码怎么去完成这个登录认证呢 他一样也需要告诉系统 我是谁
像系统证明我是谁 那我们后面等讲完整个流程 我们可以再回到这个问题上来说 OK我我我我们可以先暂时跳过这个流程啊 我们我们想一下刚刚的那个登录中 他应该是有分一些角色嘛 他有哪些角色呢 首先第一个是你的待登录设备 一般来说就是叫他PC端
我一般就是你PC端要登录手机给他扫个码嘛 那还有一个是已登录的扫码设备 就是用来扫别人的啊 这个就是移动端 或者你说手机端都可以啊 然后还有因为它可能是IPAD嘛 我们就就直接叫它移动端了 还有一个是我们你要处理的
处理那些登录认证流程的服务端对吧 这这这个少不了啊 这是我们有的几个角色 那他们之间就承担着一些不同的 承担着一些不同的职责吧 可以说是那我们前面一直都在讲扫码扫码 那二维码到底是一个什么样的东西呢 这个的话因为视频篇幅关系啊 就我不会在这里跟你去讲二维码很深的原理
或者说跟你从头娓娓道来 这个文章和B站视频特别多 就是大家可以自己去搜一下 我就直接讲讲结论了 我们可以我们就把它类比为一维的条形码 就是我们商场里面能看到的 就是去扫那个商品吗 或者说你一个书本后面 不是都可能会有那种一条一条的条形码吗
那它这个东西无论说它是二维码还是一维码 它最终映射到的是一个什么东西呢 就是一个code 那这个code又是什么呢 它无非就是一个字符串 看你相对应的app怎么去 或者应用程序怎么去解析 它 一般来说比较常用的就是URL 你可以去扫那个微信的去试试嘛 那出来的可能就是一个UI了
或者说你去扫那个B站的 我可以给大家演示一下 就我们打开微信 可以看到一个这样的一个扫码登录的呃 微信二维码 那我们这个时候我把这个二维码图片 我给保存下来 我截图一下 OK我把这个图片保存下来 然后我打开 我打开草料二维码的解码器 OK我我我这边直接上传图片解码
我们可以看到他解码出来的结果就是一个URLL 就在这边就是这样的一串URLL 它可能解析出来的一个id 就是这个看看这个是最关键的一个东西嘛 这是我们后面会讲到的一个二维码id 我们如果去拿B站的试验一下 应该结果也是一样的 啊这是B站 我们可以看到也是解析出来的一个ULL
他这里面的就包含了一个qr code key 看到了吗 这边OK我们回到回到白板 就是说我们现在能知道了二维码 你如果做一个扫码动作 对它解析出来的 它就是一个字符串 我们就能拿到他的一个唯一标识 甚至说你就是拿到一个直接可用的URL 那我们现在知道二维码它是一个什么样的东西 之后呢
我们就可以来去梳理一下二维码 它的整个一个状态流程 就是说那个状态机是怎么样的 那我们我们可以就来画一下嘛 首先呢他一进来哈 它应该是一个带扫码的状态 就是它从生成之后 他就一个带扫的状态嘛 带扫码 那扫码完之后 如果说我的手机啊给他扫一下
它会直接直接就登进去吗 不会它会进入一个扫码待确认的状态 那我们直接简写了待确认 这是他的下一个状态 如果我确认了之后呢 就是我这边我去点一个确认 那如果说他通过成功了的话 那就登录成功嘛 当然了 如果他中间的验证过程出现了问题
那就登录失败了 验证失败 那这边相对应的就是验证成功 移动端点确认 这需要一个移动端去点确认的过程啊 然后这边就是移动端扫码 就我们要清楚整个状态机流转 他是因为什么动作触发了它流转 那我们最开始带扫码状态
那是怎么来的呢 它会有一个设备生成并展现 就说你是通过你的PC端设备去生成的 这个二维码 当然这也需要你服务端的配合 我后面会讲 就是说你需要从服务端拿那那边拿到一个呃 唯一的一个cod 你根据这个code再把这个二维码
用一些库函数把它给生成出来 那OK那那我们这个结束了吗 其实也还没有 因为我们刚刚看到 还有一种情况叫做过期失效了对 所以我们还有一种状态是已失效对 无论说你这个时候是已经进待确认了 还是带扫码 只要你没登进去 它都会失效 就是过期了吗 OK那我们整个状态机大概的一个流程
就是梳理出来了 这是以二维码作为主体的二维码状态机 这是整个登录对象 就是说中间的一个凭证的一个状态机 那我们前面其实讲到了 他有三个设呃 三个角色 PC端 移动端 服务端 整个流程是需要这三个端共同串起来的 才能完成这个登录
这个的话就需要我们去串起它整体的一个流程 那我们可以结合着这状状态机 然后来来梳理一下它的整整套流程嘛 我们回回忆一下前面我场外录的那个视频 首先我们是PC端 它会进入扫码登录的页面
就是我们先得进入那个页面 如果你把那个视频放很慢倍速 你能看到它是有个加载的过程 那这个过程它在干嘛呢 请求服务端以获取二维码id 它有了这个二维码id之后呢 它才能去生成相相应的二维码嘛 但中间我漏了一个 他请求完服务端之后 那服务端总得处理嘛
那服务端这个时候就会生成二维码id 如果严格一点的话 它其实这个时候还会有个步骤 是与请求设备绑定 但是B站其实没做 就大家可以去抓它的接口 看他其实没做这个事情 然后写入存储后返回 注意哦 他这里是带有效期的
既然它带有效期 我们就可以怎么去做它 这个这边我们其实直接你去用一个最简单的话 你用REDIS就能做了 你直接去结合他那个expire time的能力嘛 而且他也是很符合那种单点的 你的key就用那个二维码id就可以了 因为这个二维码id 会串起我们后面的整个的流程 咱们用二维码id来做它的key
然后video去放一些其他的信息 放一些用户相关的信息 或者说设备相关的信息 一般我们说设备 设备信息其实最重要的就是它的一个设备id 因为设备id这个东西是能指向你的 一个唯一设备嘛 因为有时候也涉及到一些兽性问题 完了之后呢 这个时候你才可以真的去把那个二维码id 返给PC端 然后PC端
这个时候他再根据二维码id生成二维码图展示 到这个时候才是我们看到的 前面那可能就零点几秒就做完了一个动作 就你点开那个登录页 然后啪生成一个二维码给你 我举个示范啊 就这样啊 对就是这个过程 OK我们接着说 然后这个时候我们我们该干嘛 该扫码了 这时候移动端啊
移动端移动端出厂了 移动端扫码解析出OMID 扫码动作其实是解析我们前面看那个什么呃 我展示的草料二维码 它就是把一个二维码图片解析为他的一个id 就是说它中间是有这么一个转换过程的 它可能是一个啊code或者你id都可以 然后到到图片啊 这是你可理讲
这是一个编码解码的过程啊 然后又又到cod 它就是编解码 然后完了之后呢 移动端再拿着移动端的token 这一步特别重要 和二维码id请求服务端登录对 因为我们说二维码id串起整个流程 好到这里 我们先停一下 移动端 拿着移动端的token
移动端的token是什么意思呢 这个东西它其实就是用来证明你是谁 和你是你的 我们我们这时候可以回来了 登录认证方式 你是在告诉系统 我我是谁 那我们这里无论怎么说 无论是手机号还是邮箱还是什么 就假设我们就是账号 假设就是说B站的话 你B站有个B站账号 对不对 那你这个token里面 应该就是有你的一个账号信息的
除此之外 因为你已经在这个你当前的这台手机上面 也是移动端上面 你登录过你的B站账号了 所以你的这台设备也是被呃授信过的 就说你这台设备上面是有 你之前通过账号密码登录 或者说账号验证码登录登进去的 那个token里面是包含一些呃认证过的信息的
这是他的一个凭证 我写在这边 就比如说呃你一个账号id加上设备id 加巴拉巴拉巴拉 他可能是有一些其他的认证信息 完了之后 你通过一个什么哈算法 比如说哈希什么的 或者是一些什么加密算法 你生成了一个token 它本质是什么 也是个string吗 这可能就涉及到一个
基于token的登录认证方式了 这个以后有机会的话再讲 这边只能先简单带过一下 总之它就是会生成一个这么一个登录认证凭证 或者说叫令牌 你拿着这个东西 你拿这个你就把它当做一个key一样的东西 服务端那边会把这个东西解出来 然后来识别出你是不你是谁 并且你是不是你 所以你扫码这个动作
其实就是确认说你是这个设备 且登录的是这个账号 这是二维码登录认证的一个最关键的地方 就是用你过去已经有过的证明 然后来通过扫码的这种方式来进去这个系统 OK我们回来接着说 OK那这时候我要登录进去了对吧 那服务端他总得做一些验证吗 他这个时候做验证之后
他就得绑定你的用户信息 前面应该有个解析验证绑定用户信息 因为你那个token里面是带你的账号信息的 完了之后呢 它会返回一个临时token 这个是返给谁的 返给移动端 为什么要返一个临时token呢 用于二次确认的临时token 大家应该还记得吧
就是他应该是会有一个 他是会有一个二次确认的一个过程的 他这个时候PC端的展示的二维码 进入待确认状态 也就是这个状态 这时候他扫完码了 你看我们前面做了这么多步骤 才从这个流转到这个 那代扫码是从哪里开始的呢 从做完三开始 根据二维码id生成二维码图展示出来
这个时候是带扫码 这个时候我们移动端就该拿着临时token 确认登录 为什么用一个临时token来去做一个二次确认呢 它其实主要然后还是一个安全性考虑嘛 就有点像HTTPS加密 就你可能通过一些中间交互过程中的一些数据 来生成这个临时的token
然后来反这个东西给你用于做二次确认 来证明 说确实是你这个人拿着这个临时token 来来确认登录 而不是别人 但是你说只拿着临时token 万一我被第三方劫持了怎么办 就比如说中间来了个拦路虎 把我这个token给偷走了 那他也能登 那所以只拿着临时token啊 也不够 前面其实还漏了一个东西啊
就你拿着二维码id加临时token确认登录 然后这时候还不够 你还得有一个东西 就是移动端的token 也就是上面说的这个移动端的token 你得拿着这个东西再去请求一遍服务端 来去做一个确认 这里面是带着你的用户id跟设备id信息的 就是做一个二次认证嘛 完了之后呢
服务端那边还会做一次校验 如果通过就修改二维码状态 返回登录token 在玩了 在玩了呢 然后PC端那边就成功登录了 这是一个整个成功登录的一个流程 期间如果二维码过期了 流程就终止了
那PC端那边会提示说需要从头再来 那我们前面不是列了这个状态机吗 那PC端怎么能拿到这样的一些状态呢 甚至是后面这些token 就我怎么知道他现在变成待确认 因为这都是服务端的操作嘛 我怎么知道它登录成功了呢 这其实就就是一个通信问题嘛 我我们可以选择说去轮询
它就不断的 比如隔个几百毫秒 或者说一秒你就去扫一次 看看他现在状态如何 这也是大部分网站的做法 包括B站 我后面可以去抓包看一下 然后还有一种方式是我也一样 是有PC端去请求服务端 然后这个时候我我把这个请求给hand住 等到他有变更的时候 就我建立一个长链接
等到他确实有变更的时候才去返回这个结果啊 这也是一种方式 还有一种方式就是我预做的比较多的 就是WEBSOCKET 我可以直接在服务端测 直接在有变化的时候推给PC端 让PC端能拿到这个东西 就就像一个主动推的过程嘛 拉和推我 我这边就不列了 就我们知道这个东西就行了
所以这里面其实会涉及一些流程 里面其实会涉及 可以看到有四个四个接口 首先是第二步 服务端生成二维码id 生成二维码id 这个是PC端请求服务端的一个接口 这是触发二维码生成的 这是一个接口 等我讲完后面几个点之后 讲完后面几个接口之后 我们可以一起到B站 我们抓包看看
然后是刚刚讲的二维码状态查询接口啊 这个可能不在我列的流程里面 但是你要知道有有这么一个接口 就比如说它就是一个轮询 我不断的把我的那个呃qr code传给你啊 或者二维二维码id 然后你返给我是一个status 它可能是一个数字或一个字符串 或者就各种形式 其次说就是说我登录成功之后
你你得把那个token拿给我嘛 这是一个这我们讲了两个接口了 这是登录设备的 在登录设备上去请求服务端的两个接口 这是被扫码设备的 至于你扫码设备本身呢也是有一些接口 这个我我我我就不去展示抓包了 因为这个可能难难弄一点 但你要知道有一有这些 就前面那两个可能空手打开还能抓一抓
然后讲扫扫码设备 扫码设备的话 你得有个扫码接口嘛 第四步 移动端扫码解析出二维码id之后 到第五步 拿着移动端的token和OMID请求服务端登录 这个过程其实就是移动端扫码 从待扫码到待确认的一个过程 然后去拿到一个用于二次确认的 一个临时token的接口 这是一个接口用于扫码
然后推动它的状态机从这里到这里 那还有一个呢就应该就是从这里到这里的嘛 这条路或者这条路 那就是这个他拿着临时token 还有相关的其他的一些信息嗯 来去做一个做一个最终的确认登录两个接口 两个接口本质上都是都是一个认证过程 就像你TCPTCP通信有个三次握手嘛
就类似或者说你HTTPS建立那个通行过程 这是扫码设备的两个关键接口 前面讲了四个移动端 两个PC端 两个好 那我们现在可以进入到B站那边抓包的画面 OK我们现在打开开发者工具 那我们把这个network打开 我们注意看右边的请求啊 我这时候点一个登录 这是我们看到一个什么generate
可以看到q web qr code generate 它这里面就是有一些带了一些参数嘛 什么payload 它主要是source表明个来源 然后go u i l 但这些其实都我认为其实都不重要 重要的是我们看它data它返回什么 它返回给你了一个qr code key 我们拉过来看 我把我前面视频的那个呃其中的一个截图
就我之前草料二维码那边扫码扫过那UI咯 拿下来了 大家看一下这两个UIL是不是长得一样啊 它就是一个东西啊 就是你这个二维码解析出来的就是这个东西 那我们看到这个qr code key 这个东西就是在这个里面嘛 就是一个东西 但这个东西它一定得去靠 我们前面说的设备id生成吗 其实也不用啊 我试过我可以给大家看一下
咱们就用这一串 OK就我直接刻了这个链接 我没有带其他参数 但是他一样能能把这个东西给返回给我 他不需要不需要那个什么设备 设备id 我一样能生成这个东西 就是我请求了 我就我就给你生成这样一个东西 那我们可以看到啊 这边因为时间比较长 它已经已经过期了 然后我们可以看到旁边这么多请求
他一直在轮询轮询轮询哎 然后他的二维码已过期之后 他停止了 他没有再接着轮巡了 就说到这个之后他就停了 然后可以看下前面的一些东西 这个PO也就是说我们说在PC端上面 不断的去轮询服务端拿状态的一个接口 我们我们去看它的一个参数 payload传到qr code key 就是刚刚前面看的那个
我们再去看一下它的返回结果 code code也就是它的一个status 然后message好未扫码 就是对这个状态的一个描述 OK然后token token是没有的 因为你都还没登录嘛 就没有token 这个状态是是最重要 然后还有这个token嘛 那其他我们先不看啊 这时候我们再往下走 往下走走走走 走到后面他开始我们看这个这个也是微商嘛
哎当我们到这是倒数第二个 我们看倒数第一个二维码已失效 到这里 你看cod变了 二维码已失效 这个时候我就不会再去再去请求了 然后我把这些都清一清啊 然后我们再重新点击一下 就重新生成 看他又generate了一个啊 你看又开始轮询了 看它又又回到这个状态了 然后generate这个时候给的qr code key 就是另外一个了
我们这时候我这边登录一下B站 OK我这里扫码一下好 他变了 这个时候再去扫它哎 就变成二维码扫码啊 以扫码为确认 就我刚刚说待确认的一个状态 完了之后呢 他这时候你看还在一直不停的轮询 一直不停轮询 这个时候我只要点击它的一个确认登录好 我们看一下我确认登录 然后这时候还在轮询哎 然后就变了
他就开始变了 我们去看最后一个pull 我FTER一下pull 我去看最后一个PO 你看这时候他就返回了一个refresh token 然后还返了返了一串啊 你去做一个登录跳转的一个链接 然后还有包括你的一个时间戳 对 这其实就就跟我们前面讲的是一样的嘛
OK那这期视频就是呃通过一些更具体的例子吧 然后给大家讲了一下这个二维码的登录设计 那希望本期视频能对你有所帮助 喜欢本支视频的话 欢迎留下你的点赞评论收藏 谢谢
Loading video analysis...