切換語言為:簡體

Google令牌在前端和node端的使用

  • 爱糖宝
  • 2024-11-18
  • 2025
  • 0
  • 0

背景

Google令牌,其實不侷限於google令牌,其他的很多手機令牌背後的邏輯都是差不多的,畢竟金鑰和令牌計算邏輯已經開源了。就不贅述了

實現邏輯

當前令牌 = fn (金鑰, 當前時間), 也就是當前令牌的六位數字只與金鑰和當前時間有關係。 金鑰和令牌生成的演算法已經開源了。也就意味著:

  1. 只要拿到金鑰,就可以計算出當前的令牌。聽著有點不安全,但是吧,金鑰都洩露了,那還談演算法的安全不安全就沒意義了。

  2. 因為只需要金鑰和時間,所以內網環境下離線使用也是完全可以的,只是要確保內外網時間一致。

  3. 演算法都是開源的,也就意味著你不用google-auth-library來做,用其他的封裝好的npm包生成的金鑰也是可以用手機上的谷歌令牌軟體識別。(不嚴謹,意思是這麼個意思)

實現

這裏我用otplib來演示一下,如果想用google-auth-library也可,但是吧,就是後者在配置上相對麻煩一丟丟。

生成金鑰

不多贅述,直接上程式碼。

import { authenticator } from 'otplib';
const secret = authenticator.generateSecret();

完了?額,確實完了,就一行程式碼。
核心就是呼叫的generateSecret方法來生成一個金鑰。這個金鑰有兩個作用:

  1. 用來讓手機上的谷歌令牌軟體識別進行繫結。

  2. 當輸入令牌後,令牌的校驗。

令牌的繫結

通常會採用生成一個二維碼的方式來做谷歌令牌的繫結。

// 生成google手機令牌可以識別的二維碼URI
const googleKeyUri = authenticator.keyuri('當前使用者名稱字','產品名字',secret);
// 然後直接渲染就好,這裏使用的qrcode.react,生成一個二維碼,vue或者在nodejs參考其他的二維碼生成方式。
<QRCodeCanvas value={googleKeyUri} />

使用者使用手機掃描二維碼,令牌就成功繫結上了。

令牌的校驗

不多贅述,直接上程式碼。

const { authenticator } = require('otplib');
const check = (六位令牌碼) => authenticator.check(六位令牌碼, secret);

呼叫authenticator的check方法即可在服務端進行校驗,將手機令牌的六位令牌碼和先前的金鑰作為引數即可。

值得注意的地方

這裏只是寫了核心的程式碼,金鑰和使用者的服務端儲存,二維碼的展示方式,是否繫結成功的驗證都沒有寫,具體可以根據實際需求擴充套件。

  1. 在服務端生成金鑰二維碼再給前端展示也是可以的。

  2. 要做的完善一點的話,我們在第一次繫結上的時候需要進行是否繫結成功的確認,難免會有一些未知原因,伺服器沒存上。

寫在最後的話

動態令牌在當下的網際網路發展中是非常常見的,其內部實現邏輯TOTP (Time-based One-Time Password)也是現在的主流,具體的密碼雜湊函式有興趣的小夥伴可以去查一查。


0則評論

您的電子郵件等資訊不會被公開,以下所有項目均必填

OK! You can skip this field.