Отсутствует кодовый_верификатор OAuth2
Я хотел создать свой Oauth2 провайдер для аутентификации в моих django приложениях. Для теста я использовал Django OAuth Toolkit и создал 2 отдельных проекта на разных портах:
http://127.0.0.1:8001 - клиент
http://127.0.0.1:8000 - провайдер
Вот все конечные точки провайдера, на которые осуществляется перенаправление для входа и подтверждения доступа:
from django.contrib import admin
from django.urls import path, include
from django.contrib.auth import views as auth_views
path('admin/', admin.site.urls),
path('o/', include('oauth2_provider.urls', namespace='oauth2_provider')),
path('accounts/login/', auth_views.LoginView.as_view(template_name='login.html'), name='login'),
path('accounts/logout/', auth_views.LogoutView.as_view(), name='logout'),
Код для страницы входа в систему:
<!DOCTYPE html>
<html>
<head>
<title>Login</title>
</head>
<body>
<h2>Login</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Login</button>
</form>
</body>
</html>
На стороне провайдера все идет нормально, я попадаю на страницу подтверждения пользователя и меня перенаправляют на специальную страницу клиента обратного вызова.
Конечные точки клиентов:
from django.contrib import admin
from django.urls import path
from client import views
urlpatterns = [
path('admin/', admin.site.urls),
path('client/login/', views.login, name='login'),
path('client/callback/', views.callback, name='callback'),
]
Просмотров клиента:
import os
import string
import random
import base64
import hashlib
from django.http import HttpResponse
from django.shortcuts import redirect, render
from requests_oauthlib import OAuth2Session
os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
CLIENT_ID = 'hR0E2tAkf8mLqOwNpPPun0dTBDU44JF8z8SgJfnJ'
CLIENT_SECRET = 'hNi3IugtuqtEFa5GonCW4ilQTnsjz2nUE1jf2WeoxaMQNZHt1pzszLGeGtpYsNXV7VHouFF79C7XMOmSJRcXrY4OEPoJuTQyIng6ONjjt4tPvJfpPJpKMFPX9MPgUpps'
REDIRECT_URI = 'http://127.0.0.1:8001/client/callback/'
AUTHORIZATION_URL = 'http://127.0.0.1:8000/o/authorize/'
TOKEN_URL = 'http://127.0.0.1:8000/o/token/'
def generate_code_verifier():
verifier = ''.join(random.choices(string.ascii_letters + string.digits, k=128))
return base64.urlsafe_b64encode(verifier.encode('utf-8')).rstrip(b'=').decode('utf-8')
def generate_code_challenge(verifier):
code_challenge = hashlib.sha256(verifier.encode('utf-8')).digest()
return base64.urlsafe_b64encode(code_challenge).rstrip(b'=').decode('utf-8')
def login(request):
oauth = OAuth2Session(CLIENT_ID, redirect_uri=REDIRECT_URI)
code_verifier = generate_code_verifier()
code_challenge = generate_code_challenge(code_verifier)
authorization_url, state = oauth.authorization_url(
AUTHORIZATION_URL,
code_challenge=code_challenge,
code_challenge_method='S256'
)
request.session['code_verifier'] = code_verifier
print(f"Saved code_verifier in session: {request.session['code_verifier']}")
return redirect(authorization_url)
def callback(request):
code = request.GET.get('code')
code_verifier = request.session.get('code_verifier')
if code_verifier is None:
return HttpResponse("Code verifier is missing in the session.")
print(f"Retrieved code_verifier from session: {code_verifier}")
oauth = OAuth2Session(CLIENT_ID, redirect_uri=REDIRECT_URI)
try:
token = oauth.fetch_token(
TOKEN_URL,
code=code,
client_secret=CLIENT_SECRET,
code_verifier=code_verifier
)
access_token = token.get('access_token')
return render(request, 'callback.html', {'access_token': access_token})
except Exception as e:
print(f"Error fetching token: {e}")
return HttpResponse(f"Error fetching token: {e}")
В методе, который отвечает за вход на стороне клиента, я получаю code_verifier и он даже отображается в консоли, но когда я перехожу к callback.html, я не могу его получить и, соответственно, получаю: "Code verifier is missing in the session".
Я не знаю, что я сделал не так и почему он не сохраняется и я не могу его восстановить? Если вам нужна дополнительная информация, я вам ее предоставлю.