Проблема при попытке реализовать Google Two Factor в приложении Laravel - PullRequest
0 голосов
/ 19 февраля 2020

Я пытаюсь создать приложение, в котором у пользователя есть возможность подключиться к google2fa. Он включает опцию в своем профиле, и затем google2fa становится активным. Однако после реализации этого урока https://www.5balloons.info/two-factor-authentication-google2fa-laravel-5/ и этого https://github.com/antonioribeiro/google2fa-laravel я получаю следующие маршруты

Route::get('/dashboard', 'PagesController@dashboard')->middleware(['auth', '2fa']);
Route::get('/complete-registration', 'Auth\RegisterController@completeRegistration');
Route::get('/', 'HomeController@index')->middleware(['auth', '2fa']);

Route::get('/2fa/enable', 'Google2FAController@enableTwoFactor');
Route::get('/2fa/disable', 'Google2FAController@disableTwoFactor');
Route::get('/2fa/validate', 'Auth\AuthController@getValidateToken');
Route::post('/2fa/validate', ['middleware' => 'throttle:5', 'uses' => 'Auth\AuthController@postValidateToken']);

Google2FAMiddleware. php

<?php
namespace App\Http\Middleware;
use App\Support\Google2FAAuthenticator;
use Illuminate\Contracts\Auth\Guard;
use Closure;
class Google2FAMiddleware
{
    /**
    * Handle an incoming request.
    *
    * @param  \Illuminate\Http\Request  $request
    * @param  \Closure  $next
    * @return mixed
    */

protected $auth;

public function __construct(Guard $auth)
{
    $this->auth = $auth;
}

public function handle($request, Closure $next)
{
    $authenticator = app(Google2FAAuthenticator::class)->boot($request);
        if ($authenticator->isAuthenticated()) {
            return $next($request);
        }
    return $authenticator->makeRequestOneTimePasswordResponse();
}

}

Google2FAAuthenticator. php

<?php
namespace App\Support;
use PragmaRX\Google2FALaravel\Support\Authenticator;

class Google2FAAuthenticator extends Authenticator
{
    protected function canPassWithoutCheckingOTP()
    {
        if(!count($this->getUser()->google2fa_secret))
        return true;
        return
        !$this->getUser()->use2fa ||
        !$this->isEnabled() ||
        $this->noUserIsAuthenticated() ||
        $this->twoFactorAuthStillValid();
    }

    protected function getGoogle2FASecretKey()
    {
        $secret = $this->getUser()->{$this->config('otp_secret_column')};
        if (is_null($secret) || empty($secret)) {
            throw new InvalidSecretKey('Secret key cannot be empty.');
        }
        return $secret;
    }
}

Пользователь. php модель

//google2fa encryption

public function setGoogle2faSecretAttribute($value){
    $this->attributes['google2fa_secret'] = encrypt($value);
}

// google2fa decryption
public function getGoogle2faSecretAttribute($value){
    // dd(decrypt($value));
    return decrypt($value);
}

public function passwordSecurity()
{
    return $this->hasOne('App\PasswordSecurity');
}

Google2FAController. php

<?php

namespace App\Http\Controllers;

use Crypt;
use Google2FA;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Validation\ValidatesRequests;
use \ParagonIE\ConstantTime\Base32;
use Illuminate\Support\Facades\Auth;


class Google2FAController extends Controller
{
    use ValidatesRequests;

    public function __construct()
    {
        $this->middleware('web');
    }

    public function enableTwoFactor(Request $request)
    {
        //generate new secret
        $secret = $this->generateSecret();

        //get user
        $user = Auth::user();

        //encrypt and then save secret
        $user->google2fa_secret = Crypt::encrypt($secret);
        $user->save();

        //generate image for QR barcode
        $imageDataUri = Google2FA::getQRCodeInline(
            $request->getHttpHost(),
            $user->email,
            $secret,
            200
        );

        // return view('user.profile', ['image' => $imageDataUri,
        //     'secret' => $secret, 'use2fa' => 1]);

        return response()->json([
            'use2fa' => 1
        ]);
    }


    public function disableTwoFactor(Request $request)
    {
        $user = $request->user();

        //make secret column blank
        $user->google2fa_secret = null;
        $user->save();

        // return view('2fa/disableTwoFactor');
        return response()->json([
            'use2fa' => 0
        ]);

    }

    /**
     * Generate a secret key in Base32 format
     *
     * @return string
     */
    private function generateSecret()
    {
        $randomBytes = random_bytes(10);

        return Base32::encodeUpper($randomBytes);
    }
}

файл конфигурации для google2fa

<?php

return [

    /*
     * Enable / disable Google2FA.
     */
    'enabled' => true,

    /*
     * Lifetime in minutes.
     *
     * In case you need your users to be asked for a new one time passwords from time to time.
     */
    'lifetime' => 0, // 0 = eternal

    /*
     * Renew lifetime at every new request.
     */
    'keep_alive' => true,

    /*
     * Auth container binding.
     */
    'auth' => 'auth',

    /*
     * 2FA verified session var.
     */

    'session_var' => 'google2fa',

    /*
     * One Time Password request input name.
     */
    'otp_input' => 'one_time_password',

    /*
     * One Time Password Window.
     */
    'window' => 1,

    /*
     * Forbid user to reuse One Time Passwords.
     */
    'forbid_old_passwords' => false,

    /*
     * User's table column for google2fa secret.
     */
    'otp_secret_column' => 'google2fa_secret',

    /*
     * One Time Password View.
     */
    'view' => 'google2fa.index',

    /*
     * One Time Password error message.
     */
    'error_messages' => [
        'wrong_otp'       => "The 'One Time Password' typed was wrong.",
        'cannot_be_empty' => 'One Time Password cannot be empty.',
        'unknown'         => 'An unknown error has occurred. Please try again.',
    ],

    /*
     * Throw exceptions or just fire events?
     */
    'throw_exceptions' => true,

    /*
     * Which image backend to use for generating QR codes?
     *
     * Supports imagemagick, svg and eps
     */
    'qrcode_image_backend' => \PragmaRX\Google2FALaravel\Support\Constants::QRCODE_IMAGE_BACKEND_IMAGEMAGICK,

];

После включения google 2 factor, после входа в систему я получаю эту ошибку:

Подсветка \ Контракты \ Шифрование \ DecryptException Полезная нагрузка недействительна.

Если я комментирую функцию getGoogle2faSecretAttribute от модели User. php, я получаю эту ошибку:

Маршрут [2fa] не определен

Я не знаю, чего мне здесь не хватает.

PS: Laravel6, последняя версия php, последняя версия mysql

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...