Ошибка Django google-auth-oauthlib insecure_transport на облачных рабочих станциях, несмотря на HTTPS и SECURE_PROXY_SSL_HEADER

Я разрабатываю приложение Django в среде Firebase Studio. Я пытаюсь внедрить Google OAuth 2.0, чтобы мои пользователи (врачи) могли подключать свои учетные записи Google Calendar, используя библиотеку Google-auth-oauthlib.

Доступ к приложению осуществляется через общедоступный URL-адрес HTTPS, предоставляемый Firebase (например, https://8000-firebase-onlinearsts-...cloudworkstations.dev).

Я настроил свой облачный проект Google, включил API календаря, настроил экран согласия OAuth и создал идентификатор клиента OAuth 2.0 для веб-приложения с правильным URI авторизованного перенаправления https:// (https://8000-firebase-onlinearsts-1753264806380.cluster-3gc7bglotjgwuxlqpiut7yyqt4.cloudworkstations.dev/accounts/google/callback/).

Однако, когда представление обратного вызова OAuth моего приложения Django (accounts.views.google_oauth_callback) пытается обменять код авторизации на токены с помощью flow.fetch_token(), я получаю следующую ошибку:

Ошибка проверки подлинности Google В процессе проверки подлинности Google произошла ошибка.

Подробная информация об ошибке: Ошибка при обмене OAuth: (insecure_transport) OAuth 2 ДОЛЖЕН использовать https.

Я не могу понять, почему я получаю эту ошибку, если я использую https.

mysite/mysite/settings.py:

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

# Google API Settings
GOOGLE_CLIENT_ID = '...'
GOOGLE_CLIENT_SECRET = '...'
GOOGLE_REDIRECT_URI = 'https://8000-firebase-onlinearsts-1753264806380.cluster-3gc7bglotjgwuxlqpiut7yyqt4.cloudworkstations.dev/accounts/google/callback/' # Matches Google Cloud Console

GOOGLE_CALENDAR_SCOPES = [
    'https://www.googleapis.com/auth/calendar.events',
    'https://www.googleapis.com/auth/calendar.readonly',
    'https://www.googleapis.com/auth/calendar',
]

Чтобы выяснить, почему ошибка insecure_transport сохраняется, я добавил инструкции отладочной печати в мое представление обратного вызова (accounts.views.google_oauth_callback) для проверки заголовков и свойств входящих запросов:

accounts/views.py:

@login_required
def google_oauth_callback(request):

    flow = get_flow(request) # get_flow sets redirect_uri using settings.GOOGLE_REDIRECT_URI

    try:
        # --- DEBUGGING CODE ---
        print("\n--- Full Request META ---")
        for key, value in sorted(request.META.items()):
            print(f"{key}: {value}")
        print("-------------------------\n")
        print(f"request.is_secure(): {request.is_secure()}")
        print(f"request.scheme: {request.scheme}")
        print(f"request.META.get('HTTP_X_FORWARDED_PROTO'): {request.META.get('HTTP_X_FORWARDED_PROTO')}")
        print(f"request.META.get('wsgi.url_scheme'): {request.META.get('wsgi.url_scheme')}")
        print("----------------------------------\n")
        # --- END DEBUGGING CODE ---

        # Error occurs on the next line
        flow.fetch_token(authorization_response=request.build_absolute_uri())

        # ... (token saving logic) ...

    except Exception as e:
        print(f"Error during OAuth exchange: {e}")
        import traceback
        traceback.print_exc()
        return render(request, 'accounts/google_auth_error.html', {'error': f'Error during OAuth exchange: {e}'})

Вывод (main) из инструкций отладки в терминале выглядит следующим образом:

--- Full Request META ---
HTTP_HOST: 127.0.0.1:8000
HTTP_REFERER: https://accounts.google.com/
HTTP_X_FORWARDED_HOST: 8000-firebase-onlinearsts-1753264806380.cluster-3gc7bglotjgwuxlqpiut7yyqt4.cloudworkstations.dev
wsgi.url_scheme: http
-------------------------

request.is_secure(): False
request.scheme: http
request.META.get('HTTP_X_FORWARDED_PROTO'): None
request.META.get('wsgi.url_scheme'): http
----------------------------------

Error during OAuth exchange: (insecure_transport) OAuth 2 MUST utilize https.

Я не могу понять, почему запрос выполняется через http, а не https, что приводит к появлению сообщения об ошибке, которое я описал выше? Есть идеи, что я делаю не так?

Спасибо,

Вернуться на верх