title: Problem when trying to implement Google Two Factor in a Laravel App
body: <p>I am trying to create an app where the user has the option to connect with google2fa. It enables the option on it's profile and then google2fa becomes active.
  However, after implementing this tutorial <a href="https://www.5balloons.info/two-factor-authentication-google2fa-laravel-5/" rel="nofollow noreferrer">https://www.5balloons.info/two-factor-authentication-google2fa-laravel-5/</a> and this one <a href="https://github.com/antonioribeiro/google2fa-laravel" rel="nofollow noreferrer">https://github.com/antonioribeiro/google2fa-laravel</a> , I end up with the following routes</p>
  
  <pre><code>Route::get('/dashboard', 'PagesController@dashboard')-&gt;middleware(['auth', '2fa']);
  Route::get('/complete-registration', 'Auth\RegisterController@completeRegistration');
  Route::get('/', 'HomeController@index')-&gt;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' =&gt; 'throttle:5', 'uses' =&gt; 'Auth\AuthController@postValidateToken']);
  </code></pre>
  
  <p>Google2FAMiddleware.php</p>
  
  <pre><code>&lt;?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-&gt;auth = $auth;
  }
  
  public function handle($request, Closure $next)
  {
      $authenticator = app(Google2FAAuthenticator::class)-&gt;boot($request);
          if ($authenticator-&gt;isAuthenticated()) {
              return $next($request);
          }
      return $authenticator-&gt;makeRequestOneTimePasswordResponse();
  }
  </code></pre>
  
  <p>}</p>
  
  <p>Google2FAAuthenticator.php</p>
  
  <pre><code>&lt;?php
  namespace App\Support;
  use PragmaRX\Google2FALaravel\Support\Authenticator;
  
  class Google2FAAuthenticator extends Authenticator
  {
      protected function canPassWithoutCheckingOTP()
      {
          if(!count($this-&gt;getUser()-&gt;google2fa_secret))
          return true;
          return
          !$this-&gt;getUser()-&gt;use2fa ||
          !$this-&gt;isEnabled() ||
          $this-&gt;noUserIsAuthenticated() ||
          $this-&gt;twoFactorAuthStillValid();
      }
  
      protected function getGoogle2FASecretKey()
      {
          $secret = $this-&gt;getUser()-&gt;{$this-&gt;config('otp_secret_column')};
          if (is_null($secret) || empty($secret)) {
              throw new InvalidSecretKey('Secret key cannot be empty.');
          }
          return $secret;
      }
  }
  </code></pre>
  
  <p>User.php model</p>
  
  <pre><code>//google2fa encryption
  
  public function setGoogle2faSecretAttribute($value){
      $this-&gt;attributes['google2fa_secret'] = encrypt($value);
  }
  
  // google2fa decryption
  public function getGoogle2faSecretAttribute($value){
      // dd(decrypt($value));
      return decrypt($value);
  }
  
  public function passwordSecurity()
  {
      return $this-&gt;hasOne('App\PasswordSecurity');
  }
  </code></pre>
  
  <p>Google2FAController.php</p>
  
  <pre><code>&lt;?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-&gt;middleware('web');
      }
  
      public function enableTwoFactor(Request $request)
      {
          //generate new secret
          $secret = $this-&gt;generateSecret();
  
          //get user
          $user = Auth::user();
  
          //encrypt and then save secret
          $user-&gt;google2fa_secret = Crypt::encrypt($secret);
          $user-&gt;save();
  
          //generate image for QR barcode
          $imageDataUri = Google2FA::getQRCodeInline(
              $request-&gt;getHttpHost(),
              $user-&gt;email,
              $secret,
              200
          );
  
          // return view('user.profile', ['image' =&gt; $imageDataUri,
          //     'secret' =&gt; $secret, 'use2fa' =&gt; 1]);
  
          return response()-&gt;json([
              'use2fa' =&gt; 1
          ]);
      }
  
  
      public function disableTwoFactor(Request $request)
      {
          $user = $request-&gt;user();
  
          //make secret column blank
          $user-&gt;google2fa_secret = null;
          $user-&gt;save();
  
          // return view('2fa/disableTwoFactor');
          return response()-&gt;json([
              'use2fa' =&gt; 0
          ]);
  
      }
  
      /**
       * Generate a secret key in Base32 format
       *
       * @return string
       */
      private function generateSecret()
      {
          $randomBytes = random_bytes(10);
  
          return Base32::encodeUpper($randomBytes);
      }
  }
  </code></pre>
  
  <p>config file for google2fa</p>
  
  <pre><code>&lt;?php
  
  return [
  
      /*
       * Enable / disable Google2FA.
       */
      'enabled' =&gt; true,
  
      /*
       * Lifetime in minutes.
       *
       * In case you need your users to be asked for a new one time passwords from time to time.
       */
      'lifetime' =&gt; 0, // 0 = eternal
  
      /*
       * Renew lifetime at every new request.
       */
      'keep_alive' =&gt; true,
  
      /*
       * Auth container binding.
       */
      'auth' =&gt; 'auth',
  
      /*
       * 2FA verified session var.
       */
  
      'session_var' =&gt; 'google2fa',
  
      /*
       * One Time Password request input name.
       */
      'otp_input' =&gt; 'one_time_password',
  
      /*
       * One Time Password Window.
       */
      'window' =&gt; 1,
  
      /*
       * Forbid user to reuse One Time Passwords.
       */
      'forbid_old_passwords' =&gt; false,
  
      /*
       * User's table column for google2fa secret.
       */
      'otp_secret_column' =&gt; 'google2fa_secret',
  
      /*
       * One Time Password View.
       */
      'view' =&gt; 'google2fa.index',
  
      /*
       * One Time Password error message.
       */
      'error_messages' =&gt; [
          'wrong_otp'       =&gt; "The 'One Time Password' typed was wrong.",
          'cannot_be_empty' =&gt; 'One Time Password cannot be empty.',
          'unknown'         =&gt; 'An unknown error has occurred. Please try again.',
      ],
  
      /*
       * Throw exceptions or just fire events?
       */
      'throw_exceptions' =&gt; true,
  
      /*
       * Which image backend to use for generating QR codes?
       *
       * Supports imagemagick, svg and eps
       */
      'qrcode_image_backend' =&gt; \PragmaRX\Google2FALaravel\Support\Constants::QRCODE_IMAGE_BACKEND_IMAGEMAGICK,
  
  ];
  </code></pre>
  
  <p>After enabling google 2 factor, after login, I get this error:</p>
  
  <blockquote>
    <p>Illuminate\Contracts\Encryption\DecryptException
    The payload is invalid.</p>
  </blockquote>
  
  <p>If I comment the getGoogle2faSecretAttribute function from the User.php model, I get this error:</p>
  
  <blockquote>
    <p>Route [2fa] not defined</p>
  </blockquote>
  
  <p>I don't know what I'm missing here.</p>
  
  <p>P.S: Laravel6, latest version of php, latest version of mysql</p>