Skip to content

OAuth2 RefreshError: google.auth.exceptions.RefreshError: ('invalid_grant: Bad Request', {'error': 'invalid_grant', 'error_description': 'Bad Request'}) #14

@Tuisto59

Description

@Tuisto59

Hello I have trouble with a persisting error despite I change the refresh token

Stacktrace error :

Internal Server Error: /accounts/login/
Traceback (most recent call last):
  File "C:\Users\user\AppData\Local\pypoetry\Cache\virtualenvs\my-project-django-pZNbMM_w-py3.11\Lib\site-packages\django\core\handlers\exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user\AppData\Local\pypoetry\Cache\virtualenvs\my-project-django-pZNbMM_w-py3.11\Lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user\AppData\Local\pypoetry\Cache\virtualenvs\my-project-django-pZNbMM_w-py3.11\Lib\site-packages\django\views\generic\base.py", line 104, in view
    return self.dispatch(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user\AppData\Local\pypoetry\Cache\virtualenvs\my-project-django-pZNbMM_w-py3.11\Lib\site-packages\django\utils\decorators.py", line 46, in _wrapper
    return bound_method(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user\AppData\Local\pypoetry\Cache\virtualenvs\my-project-django-pZNbMM_w-py3.11\Lib\site-packages\django\views\decorators\debug.py", line 92, in sensitive_post_parameters_wrapper
    return view(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user\AppData\Local\pypoetry\Cache\virtualenvs\my-project-django-pZNbMM_w-py3.11\Lib\site-packages\django\utils\decorators.py", line 46, in _wrapper
    return bound_method(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user\AppData\Local\pypoetry\Cache\virtualenvs\my-project-django-pZNbMM_w-py3.11\Lib\site-packages\django\views\decorators\cache.py", line 62, in _wrapper_view_func
    response = view_func(request, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user\AppData\Local\pypoetry\Cache\virtualenvs\my-project-django-pZNbMM_w-py3.11\Lib\site-packages\allauth\account\views.py", line 154, in dispatch
    return super(LoginView, self).dispatch(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user\AppData\Local\pypoetry\Cache\virtualenvs\my-project-django-pZNbMM_w-py3.11\Lib\site-packages\allauth\account\views.py", line 81, in dispatch
    response = super(RedirectAuthenticatedUserMixin, self).dispatch(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user\AppData\Local\pypoetry\Cache\virtualenvs\my-project-django-pZNbMM_w-py3.11\Lib\site-packages\django\views\generic\base.py", line 143, in dispatch
    return handler(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user\AppData\Local\pypoetry\Cache\virtualenvs\my-project-django-pZNbMM_w-py3.11\Lib\site-packages\allauth\account\views.py", line 109, in post
    response = self.form_valid(form)
               ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user\AppData\Local\pypoetry\Cache\virtualenvs\my-project-django-pZNbMM_w-py3.11\Lib\site-packages\allauth\account\views.py", line 167, in form_valid
    return form.login(self.request, redirect_url=success_url)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user\AppData\Local\pypoetry\Cache\virtualenvs\my-project-django-pZNbMM_w-py3.11\Lib\site-packages\allauth\account\forms.py", line 194, in login
    ret = perform_login(
          ^^^^^^^^^^^^^^
  File "C:\Users\user\AppData\Local\pypoetry\Cache\virtualenvs\my-project-django-pZNbMM_w-py3.11\Lib\site-packages\allauth\account\utils.py", line 167, in perform_login
    return _perform_login(request, login)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user\AppData\Local\pypoetry\Cache\virtualenvs\my-project-django-pZNbMM_w-py3.11\Lib\site-packages\allauth\account\utils.py", line 177, in _perform_login
    response = adapter.pre_login(request, login.user, **hook_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user\AppData\Local\pypoetry\Cache\virtualenvs\my-project-django-pZNbMM_w-py3.11\Lib\site-packages\allauth\account\adapter.py", line 418, in pre_login
    send_email_confirmation(request, user, signup=signup, email=email)
  File "C:\Users\user\AppData\Local\pypoetry\Cache\virtualenvs\my-project-django-pZNbMM_w-py3.11\Lib\site-packages\allauth\account\utils.py", line 376, in send_email_confirmation
    email_address.send_confirmation(request, signup=signup)
  File "C:\Users\user\AppData\Local\pypoetry\Cache\virtualenvs\my-project-django-pZNbMM_w-py3.11\Lib\site-packages\allauth\account\models.py", line 93, in send_confirmation
    confirmation.send(request, signup=signup)
  File "C:\Users\user\AppData\Local\pypoetry\Cache\virtualenvs\my-project-django-pZNbMM_w-py3.11\Lib\site-packages\allauth\account\models.py", line 126, in send
    get_adapter().send_confirmation_mail(request, self, signup)
  File "C:\Users\user\AppData\Local\pypoetry\Cache\virtualenvs\my-project-django-pZNbMM_w-py3.11\Lib\site-packages\allauth\account\adapter.py", line 606, in send_confirmation_mail
    self.send_mail(email_template, emailconfirmation.email_address.email, ctx)
  File "C:\Users\user\AppData\Local\pypoetry\Cache\virtualenvs\my-project-django-pZNbMM_w-py3.11\Lib\site-packages\allauth\account\adapter.py", line 144, in send_mail
    msg.send()
  File "C:\Users\user\AppData\Local\pypoetry\Cache\virtualenvs\my-project-django-pZNbMM_w-py3.11\Lib\site-packages\django\core\mail\message.py", line 298, in send
    return self.get_connection(fail_silently).send_messages([self])
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user\AppData\Local\pypoetry\Cache\virtualenvs\my-project-django-pZNbMM_w-py3.11\Lib\site-packages\gmailapi_backend\mail.py", line 64, in send_messages
    batch.execute()
  File "C:\Users\user\AppData\Local\pypoetry\Cache\virtualenvs\my-project-django-pZNbMM_w-py3.11\Lib\site-packages\googleapiclient\_helpers.py", line 130, in positional_wrapper
    return wrapped(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user\AppData\Local\pypoetry\Cache\virtualenvs\my-project-django-pZNbMM_w-py3.11\Lib\site-packages\googleapiclient\http.py", line 1578, in execute
    self._refresh_and_apply_credentials(request, http)
  File "C:\Users\user\AppData\Local\pypoetry\Cache\virtualenvs\my-project-django-pZNbMM_w-py3.11\Lib\site-packages\googleapiclient\http.py", line 1271, in _refresh_and_apply_credentials
    _auth.refresh_credentials(creds)
  File "C:\Users\user\AppData\Local\pypoetry\Cache\virtualenvs\my-project-django-pZNbMM_w-py3.11\Lib\site-packages\googleapiclient\_auth.py", line 135, in refresh_credentials
    return credentials.refresh(request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user\AppData\Local\pypoetry\Cache\virtualenvs\my-project-django-pZNbMM_w-py3.11\Lib\site-packages\google\oauth2\credentials.py", line 431, in refresh
    ) = reauth.refresh_grant(
        ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user\AppData\Local\pypoetry\Cache\virtualenvs\my-project-django-pZNbMM_w-py3.11\Lib\site-packages\google\oauth2\reauth.py", line 365, in refresh_grant
    _client._handle_error_response(response_data, retryable_error)
  File "C:\Users\user\AppData\Local\pypoetry\Cache\virtualenvs\my-project-django-pZNbMM_w-py3.11\Lib\site-packages\google\oauth2\_client.py", line 72, in _handle_error_response
    raise exceptions.RefreshError(
google.auth.exceptions.RefreshError: ('invalid_grant: Bad Request', {'error': 'invalid_grant', 'error_description': 'Bad Request'})

Body

Environment:

  • Django Version: 4.2.11
  • Python Version: 3.11.3
  • django-gmailapi-backend Version: 0.3.2

Issue Description:
After setting up django-gmailapi-backend to send emails through my Django application using Gmail API, the first time it was working, now it's not working, I consistently encounter a RefreshError with an 'invalid_grant: Bad Request' message during the OAuth2 token refresh process. This occurs when attempting to log in via the django-allauth package, which triggers an email confirmation send action.

Despite redoing the refresh token procedure, ensuring the correct setup in the Google Cloud Console, and double-checking the client ID and secret, the issue persists.

Error Message:

google.auth.exceptions.RefreshError: ('invalid_grant: Bad Request', {'error': 'invalid_grant', 'error_description': 'Bad Request'})

Steps to Reproduce:

  1. Set up django-gmailapi-backend with OAuth2 credentials according to the documentation.
  2. Attempt to log in through django-allauth, triggering an email action.
  3. The error occurs during the OAuth2 token refresh attempt by django-gmailapi-backend.

I also use the official script of google, because the link output generated through gmail_oauth2 saying that I cant get or connect when using gmail_auth command line

https://raw.githubusercontent.com/google/gmail-oauth2-tools/master/python/oauth2.py

I have made all the combination of https/http - localhost/127.0.0.1 - with port 8000 or without it

Expected Behavior:
The refresh token should be successfully used to obtain a new access token, allowing the Gmail API to send emails without encountering a RefreshError.

Actual Behavior:
The refresh token process fails, resulting in an invalid_grant: Bad Request error, preventing email sending through the Gmail API.

Additional Context:

  • OAuth consent screen configuration, project API access, and library versions have been verified.
  • The issue persists even after generating a new refresh token.

I have a secret file where i store the JSON
all the necessary settings have been filled :

EMAIL_BACKEND = "gmailapi_backend.mail.GmailBackend"
GMAIL_API_CLIENT_ID = Secrets.GOOGLE["web"]["client_id"]
GMAIL_API_CLIENT_SECRET = Secrets.GOOGLE["web"]["client_secret"]
GMAIL_API_REFRESH_TOKEN = Secrets.GMAIL_API_REFRESH_TOKEN
DEFAULT_FROM_EMAIL = Secrets.EMAIL_HOST_USER

Questions:
Has there been a recent change in the Gmail API or Google's OAuth2 implementation that could affect token refresh behavior?

I appreciate any guidance or updates that can help resolve this issue.
I'm realy lost - I'm don't know if the wrong is at google or my code or my secrets, credentials...
Thank you very much in advance - as now I can't access to my app since it try to send the confirmation email through allauth as my database was cleaned - up so it's like the first access to the app

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions