內容目錄
前言
或許大家已經對 二階段驗證 (Two-factor authentication) 不陌生
主要就是為了防止有心人士在獲得你的帳號密碼後,就得以登入並進行犯罪
二階段驗利用手機、或任何只有你才知道的資訊來進行第二層驗證
因此提高了安全性
主要的流程如下
實例操作流程
- 使用者在登入後進入設定頁來設置二階段驗證 (可用工具如 Google Authenticator 、 Authy 等)
- 系統將藉工具產生的二階段驗碼當作 key 存入 server
- 當使用者要再次登入或進行具機敏性的操作時,須額外輸入二階段驗證工具產生的 code
- 系統驗證二階段驗證工具產生 code,在經過編碼後,是否與 server 內的 key 一致
以 Laravel 實作
以下將以 Laravel 實作
並只處理後端的部份,略過前端畫面 render
前置作業
- PHP 7.4
- Laravel 8.x LTS
- 安裝套件 : https://github.com/antonioribeiro/google2fa
composer require pragmarx/google2fa
Route
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\TestController;
Route::post('twoFa-create', [TestController::class, 'twoFaCreate']);
Route::post('twoFa-verify', [TestController::class, 'twoFaVerify']);
Controller
- 使用
Google2FA
物件來產生 key 存入 db,並回傳 url 至前端供 user 以二階段驗證工具綁定
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller as BaseController;
use PragmaRX\Google2FA\Google2FA;
class TestController extendsBaseController
public function twoFaCreate(Request $request)
{
$id = $request->id;
$google2fa = new Google2FA();
$secret = $google2fa->generateSecretKey();
// 找到目前登入的 user 並將套件產生的二階段驗證碼存入
$updateDate = [
'google2fa_token' => $secret
];
User::query()
->where('id', $id)
->update($updateDate);
// 使用工具產生 unique 的 url,讓使用者可以用二階段驗證工具掃碼存入
$qrCodeUrl = $google2fa->getQRCodeUrl(
'testUser',
'testUser@gmail.com',
$secret
);
// qrCodeUrl 可以直接用 google 的工具轉成 qrcode ,或給前端自己產。 見註1
return $qrCodeUrl;
// 根據 userId 取出
$secret = '4YI2RPLREM64FKDM';
$otp = '633672';
$valid = $google2fa->verifyKey($secret, $otp);
dd($valid);
return $google2fa->generateSecretKey();
}
}
- 註1: 這邊可以使用 google 的工具將 url 轉變成圖片
範例如下,掃了之後就可以得到otpauth://totp/test:test%40gmail.com?secret=4YI2RPLREM64FKDM
,給二階段驗證工具使用
cht=qr
chl=otpauth://totp/test:test%40gmail.com?secret=4YI2RPLREM64FKDM
choe=UTF-8
- 驗證使用者輸入的 code 是否合法
public function twoFaVerify(Request $request)
{
$user = User::findById($request->id);
$otpCode = $request->otpCode;
$google2fa = new Google2FA();
// 使用 verifyKey 來驗證是否是合法 code
$valid = $google2fa->verifyKey($secret, $otp);
// 繼續處理你要的東西...
}
- 完成!
參考資料
- https://blog.twjoin.com/筆記-google2fa-for-laravel-88b1febc2711
- https://github.com/antonioribeiro/google2fa
–https://developers.google.com/chart/infographics/docs/qr_codes?hl=zh-tw