Как я могу получить переменные сеанса, если сеансы меняются после вызова api?

Я изучаю официальный пример реализации Oauth2 для использования API quickbooks. У меня возникают проблемы с получением state_token из переменных сессии в представлении обратного вызова. Всякий раз, когда я использую представление oauth, оно отправляет запрос авторизации на сервер quickbooks. Запрос дает мне токен состояния и url, который нужно использовать для получения кода авторизации, чтобы использовать другие API в quickbooks. Я смог вывести токен состояния в представлении oauth, просто напечатав «request.session[„state“]». Это позволяет мне понять, что он сохраняется в сессии. Таким образом, когда я перенаправляюсь по указанному url, Quickbooks отправляет мне код с тем же state_token, который он выдал мне, используя представление обратного вызова в этом примере. Конечная точка обратного вызова запрашивается сервером Quickbooks для проверки, чтобы убедиться, что переданный state_token и state_token в сессии совпадают, иначе он вернет ошибку. Эта конечная точка обратного вызова была передана мной сайту Quickbooks. Но когда бы я ни пытался получить state_token в представлении обратного вызова, он всегда оказывается null/None. Поэтому всякий раз, когда представление обратного вызова проверяет, одинаковы ли токены состояния в

state_tok != auth_client.state_token:
        return HttpResponse('unauthorized', status=401)

всегда возвращается неавторизованный. Я много отлаживал и обнаружил, что идентификатор сессии, когда сессия хранится в oauth(), и когда я пытаюсь получить его в callback(), отличаются. Я просмотрел проблемы на GitHub, и, похоже, ни у кого нет такой проблемы, как у меня. Может быть, я пропустил какой-то шаг или проблема заключается в устаревших зависимостях?

Вот документация, которой я следую: https://developer.intuit.com/app/developer/qbo/docs/develop/authentication-and-authorization/faq

Вот часть из документации, на которую я ссылаюсь:

Используйте параметр 'state' в запросе авторизации, чтобы добавить уникальный токен сессии. Ваше приложение сопоставит уникальный маркер сессии с маркером, возвращенным в ответе сервера Intuit OAuth 2.0. Это подтверждает, что процесс авторизации начал пользователь, а не злоумышленник или бот.

from intuitlib.client import AuthClient
from intuitlib.migration import migrate
from intuitlib.enums import Scopes
from intuitlib.exceptions import AuthClientError

from django.shortcuts import render, redirect
from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseServerError
from django.conf import settings
from django.contrib.sessions.models import Session

from django.core import serializers

from app.services import qbo_api_call

# Create your views here.
def index(request):
    return render(request, 'index.html')

def oauth(request):
    auth_client = AuthClient(
        settings.CLIENT_ID, 
        settings.CLIENT_SECRET, 
        settings.REDIRECT_URI, 
        settings.ENVIRONMENT,
    )

    url = auth_client.get_authorization_url([Scopes.ACCOUNTING])
    request.session['state'] = auth_client.state_token

    return redirect(url)

def callback(request):
    auth_client = AuthClient(
        settings.CLIENT_ID,
        settings.CLIENT_SECRET, 
        settings.REDIRECT_URI, 
        settings.ENVIRONMENT, 
        state_token=request.session.get('state', None),
    )

    state_tok = request.GET.get('state', None)
    error = request.GET.get('error', None)

    if error == 'access_denied':
        return redirect('app:index')

    if state_tok is None:
        return HttpResponseBadRequest()
    elif state_tok != auth_client.state_token:
        return HttpResponse('unauthorized', status=401)

    auth_code = request.GET.get('code', None)
    realm_id = request.GET.get('realmId', None)
    request.session['realm_id'] = realm_id

    if auth_code is None:
        return HttpResponseBadRequest()

    try:
        auth_client.get_bearer_token(auth_code, realm_id=realm_id)
        request.session['access_token'] = auth_client.access_token
        request.session['refresh_token'] = auth_client.refresh_token
        request.session['id_token'] = auth_client.id_token
    except AuthClientError as e:
        # just printing status_code here but it can be used for retry workflows, etc
        print(e.status_code)
        print(e.content)
        print(e.intuit_tid)
    except Exception as e:
        print(e)
    return redirect('app:connected')

def connected(request):
    auth_client = AuthClient(
        settings.CLIENT_ID, 
        settings.CLIENT_SECRET, 
        settings.REDIRECT_URI, 
        settings.ENVIRONMENT, 
        access_token=request.session.get('access_token', None), 
        refresh_token=request.session.get('refresh_token', None), 
        id_token=request.session.get('id_token', None),
    )


    if auth_client.id_token is not None:
        return render(request, 'connected.html', context={'openid': True})
    else:
        return render(request, 'connected.html', context={'openid': False})

Я использовал методы print, чтобы вывести идентификатор сессии и проверить, были ли сессии одинаковыми между oauth и callback.

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