srmklive/authy

Laravel应用程序中启用双因素认证的插件

v0.7.0 2020-09-09 07:45 UTC

This package is auto-updated.

Last update: 2024-08-27 11:51:37 UTC


README

Software License Latest Version on Packagist Total Downloads StyleCI Scrutinizer Code Quality SensioLabsInsight

介绍

此插件允许您在Laravel应用程序中启用双因素认证。

仅支持Laravel 5.1或更高版本

安装

  • 使用以下命令进行安装
composer require srmklive/authy
  • 将服务提供者添加到config/app.php文件中的$providers数组中,例如
Srmklive\Authy\Providers\AuthyServiceProvider::class
  • 将别名添加到config/app.php文件中的$aliases数组中,例如
'Authy' => Srmklive\Authy\Facades\Authy::class
  • 运行以下命令以发布配置
php artisan vendor:publish --provider "Srmklive\Authy\Providers\AuthyServiceProvider"
  • 运行以下命令将用户表更改迁移到数据库
php artisan migrate
  • 在您的用户模型中添加以下行(例如 App/User.php)

    • 在类声明之前添加以下行
use Srmklive\Authy\Auth\TwoFactor\Authenticatable as TwoFactorAuthenticatable;
use Srmklive\Authy\Contracts\Auth\TwoFactor\Authenticatable as TwoFactorAuthenticatableContract;
  • 现在更改类声明。例如,如果您的类声明是
class User extends Model implements AuthenticatableContract,
                                    AuthorizableContract,
                                    CanResetPasswordContract

则更改为以下内容

class User extends Model implements AuthenticatableContract,
                                    AuthorizableContract,
                                    CanResetPasswordContract,
                                    TwoFactorAuthenticatableContract
  • 现在根据用户模型文件更改导入特质行。例如,如果该行是
use Authenticatable, Authorizable, CanResetPassword;

则更改为

use Authenticatable, Authorizable, CanResetPassword, TwoFactorAuthenticatable;
  • 最后,将$hidden变量添加/更新以隐藏用户详情数据库调用中的'two_factor_options'字段
protected $hidden = [
	'two_factor_options'
];

修改登录流程

  • 您需要将以下代码添加到您的app\Http\Controllers\Auth\AuthController.php。
    /**
     * Send the post-authentication response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @return \Illuminate\Http\Response
     */
    protected function authenticated(Request $request, Authenticatable $user)
    {
        if (Authy::getProvider()->isEnabled($user)) {
            return $this->logoutAndRedirectToTokenScreen($request, $user);
        }

        return redirect()->intended($this->redirectPath());
    }
    
    /**
     * Generate a redirect response to the two-factor token screen.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @return \Illuminate\Http\Response
     */
    protected function logoutAndRedirectToTokenScreen(Request $request, Authenticatable $user)
    {
        // Uncomment this line for Laravel 5.2+
        //auth($this->getGuard())->logout();

        // Uncomment this line for Laravel 5.1
        // auth()->logout();

        $request->session()->put('authy:auth:id', $user->id);

        return redirect(url('auth/token'));
    }

    /**
     * Show two-factor authentication page
     *
     * @return \Illuminate\Http\Response|\Illuminate\View\View
     */
    public function getToken()
    {
        return session('authy:auth:id') ? view('auth.token') : redirect(url('login'));
    }

    /**
     * Verify the two-factor authentication token.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function postToken(Request $request)
    {
        $this->validate($request, ['token' => 'required']);
        if (! session('authy:auth:id')) {
            return redirect(url('login'));
        }

        // Uncomment these lines for use in Laravel 5.2+ 
        //$guard = config('auth.defaults.guard');
        //$provider = config('auth.guards.' . $guard . '.provider');
        //$model = config('auth.providers.' . $provider . '.model');

        // Uncomment the line below for use in Laravel 5.1
        // $model = config('auth.model');

        $user = (new $model)->findOrFail(
            $request->session()->pull('authy:auth:id')
        );

        if (Authy::getProvider()->tokenIsValid($user, $request->token)) {
            // Uncomment this line for Laravel 5.2+
            //auth($this->getGuard())->login($user);

            // Uncomment this line for Laravel 5.1
	        //auth()->login($user);

            return redirect()->intended($this->redirectPath());
        } else {
            return redirect(url('login'))->withErrors('Invalid two-factor authentication token provided!');
        }
    }        
  • 添加验证双因素认证令牌的路由
Route::get('auth/token','Auth\AuthController@getToken');
Route::post('auth/token','Auth\AuthController@postToken');
  • 在resources/views/auth/token.blade.php中创建视图文件。根据您的应用程序相应更改。我在这里使用了来自AdminLTE主题的代码。
@extends('layouts.app')

@section('content')
    <div class="register-logo">
        Two-factor Authentication
    </div>

    <div class="register-box-body">
        <p class="login-box-msg">Validate your two-factor authentication token</p>
        <form method="POST" action="{{url('auth/token')}}">
            {!! csrf_field() !!}

            @if (count($errors) > 0)
                <div class="alert alert-danger">
                    <ul>
                        @foreach ($errors->all() as $error)
                            <li>{{ $error }}</li>
                        @endforeach
                    </ul>
                </div>
            @endif

            <div class="form-group has-feedback">
                <input type="type" name="token" class="form-control" placeholder="Token">
                <span class="glyphicon glyphicon-envelope form-control-feedback"></span>
            </div>
            <div class="row">
                <div class="col-xs-7"></div><!-- /.col -->
                <div class="col-xs-5">
                    <button type="submit" class="btn btn-primary btn-block btn-flat">Verify Token</button>
                </div><!-- /.col -->
            </div>
        </form>
    </div><!-- /.form-box -->
@endsection

使用方法

  • 注册用户
$phone = '405-342-5699';
$code = 1;

$user = User::find(1);

$user->setAuthPhoneInformation(
    $code, $phone
);

try {
   Authy::getProvider()->register($user);

   $user->save();
} catch (Exception $e) {
   app(ExceptionHandler::class)->report($e);

   return response()->json(['error' => ['Unable To Register User']], 422);
}
  • 通过短信发送令牌
$user = User::find(1);

try {
   Authy::getProvider()->sendSmsToken($user);
} catch (Exception $e) {
   app(ExceptionHandler::class)->report($e);

   return response()->json(['error' => ['Unable To Send 2FA Login Token']], 422);
}
  • 通过电话呼叫发送令牌
$user = User::find(1);

try {
   Authy::getProvider()->sendPhoneCallToken($user);
} catch (Exception $e) {
   app(ExceptionHandler::class)->report($e);

   return response()->json(['error' => ['Unable To Send 2FA Login Token']], 422);
}
  • 验证双因素令牌
$user = User::find(1);

try {
   Authy::getProvider()->tokenIsValid($user, $token);
} catch (Exception $e) {
   app(ExceptionHandler::class)->report($e);

   return response()->json(['error' => ['Invalid 2FA Login Token Provided']], 422);
}
  • 删除用户
$user = User::find(1);

try {
   Authy::getProvider()->delete($user);

   $user->save();
} catch (Exception $e) {
   app(ExceptionHandler::class)->report($e);

   return response()->json(['error' => ['Unable to Delete User']], 422);
}

添加新的双因素认证提供者

目前此包使用来自Authy的双因素认证服务。您也可以通过以下操作实现另一个双因素认证提供者

<?php

namespace App\Services;

use Exception;
use GuzzleHttp\Client as HttpClient;
use Srmklive\Authy\Contracts\Auth\TwoFactor\Provider as BaseProvider;
use Srmklive\Authy\Contracts\Auth\TwoFactor\Authenticatable as TwoFactorAuthenticatable;

class MyAuthProvider implements BaseProvider
{
    /**
     * Array containing configuration data.
     *
     * @var array $config
     */
    private $config;

    /**
     * Authy constructor.
     */
    public function __construct()
    {
    	// Add your configuration code here
    }

    /**
     * Determine if the given user has two-factor authentication enabled.
     *
     * @param  \Srmklive\Authy\Contracts\Auth\TwoFactor\Authenticatable $user
     * @return bool
     */
    public function isEnabled(TwoFactorAuthenticatable $user)
    {
    	// Add your code here
    }

    /**
     * Register the given user with the provider.
     *
     * @param  \Srmklive\Authy\Contracts\Auth\TwoFactor\Authenticatable $user
     * @param boolean $sms
     * @return void
     */
    public function register(TwoFactorAuthenticatable $user, $sms = false)
    {
    	// Add your code here
    }

    /**
     * Determine if the given token is valid for the given user.
     *
     * @param  \Srmklive\Authy\Contracts\Auth\TwoFactor\Authenticatable $user
     * @param  string  $token
     * @return bool
     */
    public function tokenIsValid(TwoFactorAuthenticatable $user, $token)
    {
    	// Add your code here
    }

    /**
     * Delete the given user from the provider.
     *
     * @param  \Srmklive\Authy\Contracts\Auth\TwoFactor\Authenticatable $user
     * @return bool
     */
    public function delete(TwoFactorAuthenticatable $user)
    {
    	// Add your code here
    }
}

演示应用程序

我还在一个简单的Laravel应用程序中实现了此包。您可以在这里查看安装说明。通过此应用程序,您可以执行以下操作

  • 用户登录和注册。
  • 为用户启用/禁用双因素认证。