[教程] Laravel 下实现 Google 2fa 两步认证(双因子验证)

0Tfx8F1sHl.png

我最近在我工作的其中一个项目中实现了 双因子认证Antonio Ribeiro 是一个很好的包,使用它非常简单实现, 并且 Christopher Thomas 发布了一个很酷的策略. 让我们来看看实现这些的具体步骤.

https://github.com/antonioribeiro/google2f...

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将会生成密钥及由密钥生成的二维码,用户可以扫描二维码得到秘钥.
记得使用图片标签展示二维码.

<img src="{{ $QRCode }}" alt="">

3- 存储/移除令牌

一旦用户读取二维码,它们可以输入一次性密码并提交给应用程序以验证其是否激活.

<?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默认的身份验证系统, LoginController 自带了一个 authenticated的方法用于触发身份验证之后的操作。 请求标记的完美位置。

<?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');
}

这个策略检查通过身份认证的用户是否拥有一个令牌和一个一次性的时间密码。如果令牌是空的,常规的行为是将应用重定向到主页。如果不是这样的话,用户将被重定向到/token路由上。

注意: 确保在users数据表中添加goole_oken列。

5- 登录时请求一次性密码

TokenController 将显示一个简单的视图,输入字段需要的一次性密码。

在此视图的表单提交中,目标是检索用户并根据他们的谷歌令牌验证他们的一次性密码。 如果匹配,则认证,否则再询问。

<?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- 结语

该软件包使得在任何 Laravel 应用程序中实现多因素身份验证变得非常简单。 Google2FA Facade 专注于生成密钥并在必要时进行验证,完美地处理这项工作。

另一个有意思的地方是使用 Auth Facade 在请求一次性密码时强制注销并且在令牌匹配时依靠 loginUsingId 的策略。

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://hackernoon.com/google-token-auth...

译文地址:https://learnku.com/laravel/t/7579/tutor...

本帖已被设为精华帖!
本文为协同翻译文章,如您发现瑕疵请点击「改进」按钮提交优化建议
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 4
Summer

多重要素验证(英语:Multi-factor authentication,缩写为 MFA),又译多因子认证、多因素验证、多因素认证,是一种电脑存取控制的方法,用户要通过两种以上的认证机制之后,才能得到授权,使用电脑资源[1][2]。例如,使用者要输入PIN码,插入银行卡,最后再经指纹比对,通过这三种认证方式,才能获得授权。这种认证方式可以提高安全性。

多重要素验证的概念也广泛应用于计算机系统以外的各领域。例如许多国家使用的自助出入境系统允许旅客不经人工检查即可通过边境检查。使用时,通常需要旅行证件扫描、指纹、面部特征三种要素结合来验证身份。

双重认证是多重要素验证中的特例,只使用两种认证机制。

扩展阅读:http://www.ruanyifeng.com/blog/2017/11/2fa...

6年前 评论
颜⑧

那么巧,这2周给公司做这个,目前在测试环境下 cordova做手机端,django做服务端。

6年前 评论

getQRCodeGoogleUrl 方法没找到

3年前 评论
Dark_Pony 1年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!