php 实现扫码登录
PHP 实现扫码登录的流程
扫码登录的核心流程分为两部分:前端生成二维码并轮询状态,后端验证扫码状态并返回登录凭证。以下是具体实现方法:
生成唯一二维码
-
创建临时令牌
在用户访问登录页面时,后端生成一个唯一令牌(如UUID)并存入Redis或数据库,设置较短的有效期(如300秒):$token = bin2hex(random_bytes(16)); $redis->setex("scan_token:$token", 300, 'waiting'); // 状态初始为等待 -
返回二维码内容
将令牌拼接成扫码登录URL(如https://example.com/scan?token=xxx),通过前端生成二维码:$qrUrl = "https://example.com/scan?token=$token"; echo json_encode(['qr_url' => $qrUrl]);
移动端扫码处理
-
解析二维码内容
移动端APP扫描二维码后,提取URL中的令牌,携带用户身份(如已登录的APP session)调用后端验证接口:// 移动端请求示例 POST /api/scan_confirm Body: { "token": "xxx", "user_id": 123 } -
验证并更新令牌状态
后端检查令牌是否存在且未过期,若合法则更新状态为“confirmed”并关联用户ID:if ($redis->exists("scan_token:$token")) { $redis->setex("scan_token:$token", 60, json_encode([ 'status' => 'confirmed', 'user_id' => $user_id ])); }
前端轮询状态
-
定时检查令牌状态
前端通过AJAX每2秒查询一次令牌状态,直到超时或状态变更:// 后端处理轮询请求 $data = $redis->get("scan_token:$token"); if ($data && json_decode($data)->status === 'confirmed') { echo json_encode(['status' => 'success', 'user_id' => $user_id]); } -
完成登录跳转
当前端收到“success”状态后,后端生成登录凭证(如Session或JWT),返回给前端完成登录:$_SESSION['user_id'] = $user_id; setcookie('auth_token', generateJWT($user_id), time()+3600);
安全增强措施
-
限制令牌使用次数
每个令牌仅允许一次成功确认,防止重放攻击。 -
HTTPS传输
确保所有接口和二维码URL通过HTTPS传输,避免中间人攻击。 -
短时效设计
二维码和令牌的过期时间需足够短(建议1-5分钟)。
完整实现需结合具体框架(如Laravel或ThinkPHP)调整,但核心逻辑保持一致。






