Always getting error "invalid_code"
Bundle version: 7.5.0 Symfony version: 7.1 PHP version: 8.2
Description
I implemented the scheb/2fa-bundle for the Google Authenticator, I am able to add it to the app, but if I try to login, I only get the error "code_invalid".
To Reproduce
Additional Context
security.yaml
security:
# https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
password_hashers:
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
# https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
providers:
#users_in_memory: { memory: null }
app_user_provider:
entity:
class: App\Entity\User
property: username
firewalls:
#dev:
# pattern: ^/(_(profiler|wdt)|css|images|js)/
# security: false
main:
lazy: true
provider: app_user_provider
pattern: ^/
form_login:
login_path: app_login
check_path: app_login
username_parameter: _username
password_parameter: _password
default_target_path: app_dashboard
enable_csrf: true
csrf_token_id: 'authenticate'
csrf_parameter: '_csrf_token'
logout:
path: app_logout
two_factor:
auth_form_path: 2fa_login
check_path: 2fa_login_check
enable_csrf: true
csrf_token_id: 'authenticate'
csrf_parameter: '_csrf_token'
default_target_path: app_dashboard
remember_me:
secret: '%kernel.secret%'
lifetime: 604800
path: /
always_remember_me: true
# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#the-firewall
# https://symfony.com/doc/current/security/impersonating_user.html
# switch_user: true
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
- { path: ^/2fa, role: IS_AUTHENTICATED_2FA_IN_PROGRESS }
- { path: ^/admin, roles: ROLE_ADMIN }
- { path: ^/dashboard, roles: ROLE_USER }
when@test:
security:
password_hashers:
# By default, password hashers are resource intensive and take time. This is
# important to generate secure password hashes. In tests however, secure hashes
# are not important, waste resources and increase test times. The following
# reduces the work factor to the lowest possible values.
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface:
algorithm: auto
cost: 4 # Lowest possible value for bcrypt
time_cost: 3 # Lowest possible value for argon
memory_cost: 10 # Lowest possible value for argon
scheb_two_factor.yaml
scheb_two_factor:
security_tokens:
- Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken
- Symfony\Component\Security\Http\Authenticator\Token\PostAuthenticationToken
google:
enabled: true
server_name: "shortdot.local"
issuer: "Shortdot Dashboard"
digits: 6
leeway: 15
template: "security/2fa_form.html.twig"
trusted_device:
enabled: false
ip_whitelist:
- "127.0.0.1"
- "::1"
In my Logs I get this messages
172.19.0.4 - 26/Aug/2024:08:41:10 +0200 "GET /index.php" 404
NOTICE: PHP message: [info] Matched route "2fa_login_check".
NOTICE: PHP message: [debug] Read existing security token from the session.
NOTICE: PHP message: [debug] User was reloaded from a user provider.
NOTICE: PHP message: [debug] Checking for authenticator support.
NOTICE: PHP message: [debug] Checking support on authenticator.
NOTICE: PHP message: [debug] Checking support on authenticator.
NOTICE: PHP message: [debug] Authenticator does not support the request.
NOTICE: PHP message: [debug] Checking support on authenticator.
NOTICE: PHP message: [debug] Authenticator does not support the request.
NOTICE: PHP message: [debug] Notified event "Symfony\Component\Security\Http\Event\CheckPassportEvent" to listener "Symfony\Component\Security\Http\EventListener\UserProviderListener::checkPassport".
NOTICE: PHP message: [debug] Notified event "Symfony\Component\Security\Http\Event\CheckPassportEvent" to listener "Symfony\Component\Security\Http\EventListener\UserProviderListener::checkPassport".
NOTICE: PHP message: [debug] Notified event "Symfony\Component\Security\Http\Event\CheckPassportEvent" to listener "Symfony\Component\Security\Http\EventListener\CsrfProtectionListener::checkPassport".
NOTICE: PHP message: [debug] Notified event "Symfony\Component\Security\Http\Event\CheckPassportEvent" to listener "Symfony\Component\Security\Http\EventListener\UserCheckerListener::preCheckCredentials".
NOTICE: PHP message: [debug] Notified event "Symfony\Component\Security\Http\Event\CheckPassportEvent" to listener "Symfony\Component\Security\Http\EventListener\CheckCredentialsListener::checkPassport".
NOTICE: PHP message: [debug] Notified event "Symfony\Component\Security\Http\Event\CheckPassportEvent" to listener "Scheb\TwoFactorBundle\Security\Http\EventListener\CheckTwoFactorCodeListener::checkPassport".
NOTICE: PHP message: [info] Authenticator failed.
NOTICE: PHP message: [info] Two-factor authentication request failed.
NOTICE: PHP message: [debug] The "Scheb\TwoFactorBundle\Security\Http\Authenticator\TwoFactorAuthenticator" authenticator set the failure response.
NOTICE: PHP message: [debug] Clearing remember-me cookie.
NOTICE: PHP message: [debug] Notified event "Symfony\Component\Security\Http\Event\LoginFailureEvent" to listener "Symfony\Component\Security\Http\EventListener\RememberMeListener::clearCookie".
NOTICE: PHP message: [debug] The "Scheb\TwoFactorBundle\Security\Http\Authenticator\TwoFactorAuthenticator" authenticator set the response. Any later authenticator will not be called
Please check if your server time and time on the 2fa device is configured correctly and in sync. The Google Authenticator code is time based and when time on the two devices is to much apart, it is impossible to enter a correct code. You have a leeway of 15 secs defined, which might not be enough.
I now used the Timezone Europe/Vienna (which is my timezone) for the Server and my client but it still does not work, also I am not able to define a leeway of like 30 seconds
Same time zone is not really necessary. Important thing is that both devices must have their time mostly in any in UTC time respectively. A time difference bigger than the configured leeway will lead to problems. So a server should be synced with a time providing service (NTP server) and the phone is ideally synced with phone network time. That way the time drift is kept to a minimum. Also Google Authenticator app has an option to sync time manually.
The other thing to check would be if both server-side and 2fa app have the same secret code configured. Otherwise it will be impossible to get the correct code.
Okay I will try this, I run the Application in Docker could this make any problem?
Fixed it! it was the Timezone Thank you so much!