二维码扫码登录业务详解

5,947 阅读3分钟

二维码扫码登录业务详解

前言

二维码登录 顾名思义 重要是在于登录这俩个字

登录简单点来说可以概括为俩点

  • 告诉系统我是谁
  • 向系统证明我是谁

下面我们就会围绕着这俩点来展开详细说明

原理解析

其实大部分的二维码 都是一个url地址

我们以掘金扫码登录为例来进行剖析

image-20240711145306580

我们进行一个解析

image-20240711145434556

juejin.cn/app?next_ur…

我们可以发现她实际就是这样的一个url

所以说 我们二维码的一个操作 做出来的就是一个url地址

那么我们知道这个后 我们就可以来进行一个流程的解析。

就是一个这样简单的流程

image-20240711150137958

流程概述

简单来说氛围下面的步骤:

  1. PC端:进入二维码登录页面,请求服务端获取二维码的ID。
  2. 服务端:生成二维码ID,并将其与请求的设备绑定后,返回有效的二维码ID。
  3. PC端:根据二维码ID生成二维码图片,并展示出来。
  4. 移动端:扫描二维码,解析出二维码ID。
  5. 移动端:使用移动端的token和二维码ID请求服务端进行登录。
  6. 服务端:解析验证请求,绑定用户信息,并返回给移动端一个用于二次确认的临时token。
  7. PC端:展示二维码为“待确认”状态。
  8. 移动端:使用二维码ID、临时token和移动端的token进行确认登录。
  9. 服务端:验证通过后,修改二维码状态,并返回给PC端一个登录的token。

下面我们来用一个python的代码来描述一下这个过程。

首先是服务端:

from flask import Flask, request, jsonify
import uuid
import time
​
app = Flask(__name__)
​
# 存储二维码ID和对应的设备信息以及临时token
qr_code_store = {}
temporary_tokens = {}
​
@app.route('/generate_qr', methods=['POST'])
def generate_qr():
    device_id = request.json['device_id']
    qr_id = str(uuid.uuid4())
    qr_code_store[qr_id] = {'device_id': device_id, 'timestamp': time.time(), 'status': 'waiting'}
    return jsonify({'qr_id': qr_id})
​
@app.route('/scan_qr', methods=['POST'])
def scan_qr():
    qr_id = request.json['qr_id']
    token = request.json['token']
    if qr_id in qr_code_store:
        qr_code_store[qr_id]['status'] = 'scanned'
        temp_token = str(uuid.uuid4())
        temporary_tokens[temp_token] = {'qr_id': qr_id, 'timestamp': time.time()}
        return jsonify({'temp_token': temp_token})
    return jsonify({'error': 'Invalid QR code'}), 400
​
@app.route('/confirm_login', methods=['POST'])
def confirm_login():
    qr_id = request.json['qr_id']
    temp_token = request.json['temp_token']
    mobile_token = request.json['mobile_token']
    if temp_token in temporary_tokens and temporary_tokens[temp_token]['qr_id'] == qr_id:
        login_token = str(uuid.uuid4())
        qr_code_store[qr_id]['status'] = 'confirmed'
        return jsonify({'login_token': login_token})
    return jsonify({'error': 'Invalid confirmation'}), 400
​
if __name__ == '__main__':
    app.run(debug=True)
​

之后来看PC端:

import requests
import json
​
# 1. 请求生成二维码ID
response = requests.post('http://localhost:5000/generate_qr', json={'device_id': 'PC_device'})
qr_id = response.json()['qr_id']
​
# 2. 根据二维码ID生成二维码图片 (此处省略,可以使用第三方库生成二维码图片)
print(f"QR Code ID: {qr_id}")
​
# 7. 显示二维码进入“待确认”状态
print("QR Code Status: Waiting for confirmation")
​

之后再来看移动端的代码:

import requests
​
# 4. 扫描二维码,解析出二维码ID
qr_id = '解析出的二维码ID'
token = '移动端token'# 5. 请求服务端进行登录
response = requests.post('http://localhost:5000/scan_qr', json={'qr_id': qr_id, 'token': token})
temp_token = response.json()['temp_token']
​
# 8. 使用二维码ID、临时token和移动端的token进行确认登录
response = requests.post('http://localhost:5000/confirm_login', json={'qr_id': qr_id, 'temp_token': temp_token, 'mobile_token': token})
login_token = response.json().get('login_token')
​
if login_token:
    print("登录成功!")
else:
    print("登录失败!")
​

这样一个简单的二维码登录的流程就出来了

案例解析

了解了流程之后我们来看看其他大型网站是如何实施的 这里拿哔哩哔哩来举例。

我们可以看到她的那个json实例

{
    "code": 0,
    "message": "0",
    "ttl": 1,
    "data": {
        "url": "",
        "refresh_token": "",
        "timestamp": 0,
        "code": 86101,
        "message": "未扫码"
    }
}

我们可以发现他是不断的去发送这个请求 每过1s大概

image-20240711151538374

之后当我们扫描后发现已经变成等待确认

image-20240711151702348

当我们确认后 他会返回

image-20240711151803795

和我们说的流程大概的相同