antonioribeiro/google2fa-laravel

The isAuthenticated() method always returns false in the stateless middleware (API Rest)

cristian-home opened this issue · 3 comments

Hello.
I am building a API Rest backend so I have to use the stateless middleware. When using the stateless midleware with the bootStateless instance of the authenticator (in /pragmarx/google2fa-laravel/src/Support/Authenticator.php)
the isAuthenticated() method always returns false, this method uses the canPassWithoutCheckingOTP() method which in turn uses the twoFactorAuthStillValid() method (in /pragmarx/google2fa-laravel/src/Google2FA.php) which is the one that always returns false even after verifying the OTP.

I have a controller to verify the OTP with the Google2FA facade:

    /**
     * Checkear OTP.
     *
     * @param  \Illuminate\Http\Request $request
     * @return \App\Http\Requests\Auth\OTPRequest
     */
    public function checkOTP(OTPRequest $request)
    {
        $user = $request->user();

        $validOTP = Google2FA::verifyGoogle2FA(
            $user->{config('google2fa.otp_secret_column')},
            $request->{config('google2fa.otp_input')},
        );

        return response()->json(['result' => $validOTP]);
    }

And a POST route to perform the verification, once the request to the route is made, the response is true indicating that the OTP was verified correctly, but when making a request to another route with the stateless middleware the twoFactorAuthStillValid() method returns false which causes the middleware to block the request.

Am I doing something wrong?
Should I modify the middleware and implement some mechanism that saves the status of the verified OTP for the API Rest?

If I understand correctly, being Stateless requires that no state of the application session is stored on the server being so I can not store the state of an OTP already validated. I am currently using laravel passport for authentication, to achieve to integrate 2fa correctly what I should do is that in the same authentication request where I send the user and password, I should also send the otp code if the user has 2fa enabled and thus return the access token and corresponding refresh token. to summarize, I should not send the access token until the otp is verified, and the stateless middleware would be used for the actions where it is necessary to re-enter the OTP.
Is this correct?

The only thing relates to state is the logged in user, as this package assumes you have an authenticated user, if you can do it in a stateless manner, it will probably work for you.

I've got this issue too, I'm thinking about a flag to attach with JWT token and we check from the token, isn't it?