夜火笔记

给网站加上谷歌身份验证器 实现两步验证2FA动态密码

2023-04-28
笔记 google2FA
3分钟
547字

之前没做过给网站接入谷歌身份验证器,记录一下。

概念纠正

我之前一直以为谷歌身份验证器是联网的,需要从谷歌获取动态验证码,或者从接入的网站通信获取。

实际的运行原理应该是:

  1. 用户从网站申请开启双因素验证(2FA,两步验证)
  2. 网站生成秘钥并存储
  3. 网站将秘钥展示给用户
  4. 用户使用谷歌身份验证器扫码或自行保存

之后网站就可以对开启的用户进行双因素验证了。实际网站和用户之间的动态密码,并不是通信获取的,而是双方都是使用TOTP算法 对秘钥,进行计算,获得的动态密码。

实现

目前手上这个需要加双因素验证的网站是php的,于是好玩的一幕来了,我翻遍了谷歌官网都没找到相关的内容,能找到的都是第三方的实现,不知道是怎么回事。

找到的第三方实现的库:https://github.com/antonioribeiro/google2fa

剩下的似乎也没多少好说的,就是引入库,然后按着上方的流程做就可以了。

生成

1
// 引入 google2fa
2
// ...
3
4
// 生成秘钥
5
$secret = google2fa::generateSecretKey(32);
6
7
// 持久化保存$secret
8
// ...
9
10
// 生成二维码链接
11
$qrCodeUrl = google2fa::getQRCodeUrl(
12
'[公司名或网站名]',
13
'用户名称或邮箱',
14
$secret
15
);
7 collapsed lines
16
17
// 展示二维码给用户 这里用的是 phpqrcode
18
$QR_base64 = QRcode::png($qrCodeUrl, false, 'Q', 6, 1);
19
$image_qr = imagecreatefromstring(base64_decode($QR_base64));
20
21
Header("Content-type: image/png");
22
ImagePng($image_qr);

验证用户的动态密码

1
// $code 为用户提交的动态验证码
2
// $secret 为服务器保存的秘钥
3
$res = google2fa::verifyKey($secret, $code, 0); // 这里的0需要注意一下 后面细说
4
if($res!==FALSE){
5
echo 'ok';
6
}else{
7
echo 'no';
8
}

上面的0,在文档里 Validation Window,这里感觉应该理解为验证时间窗口。默认为4,每30秒生成一个新动态码,4个就是4 * 30,2分钟,因此一个动态码验证窗口包含前2分钟和后2分钟。

主要是怕服务器时间与身份验证器时间有误差,可以做一定兼容。

本文标题:给网站加上谷歌身份验证器 实现两步验证2FA动态密码
文章作者:夜火/xloong
发布时间:2023-04-28
Copyright 2026
站点地图