我最近在我工作的其中一個項目中實現(xiàn)了 雙因子認證
. Antonio Ribeiro 是一個很好的包,使用它非常簡單實現(xiàn), 并且 Christopher Thomas 發(fā)布了一個很酷的策略. 讓我們來看看實現(xiàn)這些的具體步驟.
1- 安裝google2fa-laravel
composer require pragmarx/google2fa-laravel
2- 生成二維碼
用戶首先需要的是一種激活或禁用多重要素驗證的方法鳍征。一種方法是開放一個profile/token
的GET請求,它會向沒有私鑰的用戶渲染出激活視圖,向有私鑰的用戶渲染出禁用視圖.
<?php
namespace App\Http\Controllers\Profile;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Facades\PragmaRX\Google2FA\Google2FA;
class GoogleTokenController extends Controller
{
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Show the application dashboard.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$user = auth()->user();
if (is_null($user->google_token)) {
return $this->showEnableTokenForm($user);
}
return view('app.profile.token.disable', ['user' => $user]);
}
/**
* Show Form with Key and QRCode for the User to enable it.
*
* @param $user
* @return mixed
*/
private function showEnableTokenForm($user)
{
$key = Google2FA::generateSecretKey(64);
$google2fa_url = Google2FA::getQRCodeGoogleUrl(
'Application Name',
$user->email,
$key
);
return view('app.profile.token.enable', [
'user' => $user,
'key' => $key,
'QRCode' => $google2fa_url
]);
}
}
在方法 showEnableTokenForm
中,Google 2fa Facede將會生成密鑰及由密鑰生成的二維碼,用戶可以掃描二維碼得到秘鑰.
記得使用圖片標(biāo)簽展示二維碼.
<img src="{{ $QRCode }}" alt="">
3- 存儲/移除令牌
一旦用戶讀取二維碼,它們可以輸入一次性密碼并提交給應(yīng)用程序以驗證其是否激活.
<?php
/**
* @param Request $request
* @return \Illuminate\Http\RedirectResponse
*/
public function update(Request $request)
{
if (is_null($request->get('token'))) {
return $this->disableToken();
}
$secretKey = $request->get('secret');
$token = $request->get('token');
if (Google2FA::verifyKey($secretKey, $token)) {
auth()->user()->update(['google_token' => $secretKey]);
return redirect('/profile/token')->with('success', 'Google Token successfully enabled!');
}
return redirect('/profile/token')->withErrors(['error' => 'The provided token does not match.']);
}
/**
* @return \Illuminate\Http\RedirectResponse
*/
private function disableToken()
{
auth()->user()->update(['google_token' => null]);
return redirect('/profile/token')->with('success', 'Google Token successfully removed!');
}
如果用戶提交了正確的一次性密碼, Google2FA 門面將會驗證并將這個秘鑰存儲在用戶表中.
4- 身份驗證方法
激活令牌之后, 下一步是在登錄進程中使用它。使用Laravel默認的身份驗證系統(tǒng), LoginController
自帶了一個 authenticated
的方法用于觸發(fā)身份驗證之后的操作。 請求標(biāo)記的完美位置诗充。
<?php
protected function authenticated(Request $request, $user)
{
if (is_null($user->google_token)) {
return redirect()->intended($this->redirectTo);
}
Auth::logout();
$request->session()->put('user-id', $user->id);
return redirect('/token');
}
這個策略檢查通過身份認證
的用戶是否擁有一個令牌和一個一次性的時間密碼顽频。如果令牌是空的,常規(guī)的行為是將應(yīng)用重定向到主頁骇陈。如果不是這樣的話宠页,用戶將被重定向到/token
路由上左胞。
注意: 確保在users數(shù)據(jù)表中添加goole_oken列。
5- 登錄時請求一次性密碼
TokenController
將顯示一個簡單的視圖举户,輸入字段需要的一次性密碼烤宙。
在此視圖的表單提交中,目標(biāo)是檢索用戶并根據(jù)他們的谷歌令牌驗證他們的一次性密碼俭嘁。 如果匹配躺枕,則認證,否則再詢問。
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Models\Main\Admin;
use Facades\PragmaRX\Google2FA\Google2FA;
use Illuminate\Http\Request;
class TokenController extends Controller
{
public function index()
{
return view('auth.token');
}
public function authenticate(Request $request)
{
$user = Admin::findOrFail($request->session()->get('user-id'));
$token = $request->get('token');
if (Google2FA::verifyKey($user->google_token, $token)) {
$request->session()->remove('user-id');
auth()->loginUsingId($user->id);
return redirect('/home');
}
return redirect('/token')->withErrors(['error' => __('Invalid Token')]);
}
}
6- 結(jié)語
該軟件包使得在任何 Laravel
應(yīng)用程序中實現(xiàn)多因素身份驗證變得非常簡單屯远。 Google2FA Facade 專注于生成密鑰并在必要時進行驗證蔓姚,完美地處理這項工作捕虽。
另一個有意思的地方是使用 Auth Facade 在請求一次性密碼時強制注銷并且在令牌匹配時依靠 loginUsingId
的策略慨丐。