Не работает метод set_cookie класса RedirectResponse
Есть код аутентификации и авторизации пользователей на sqladmin:
class AdminBack(AuthenticationBackend):
async def authenticate(self, request: Request) -> Response | bool:
token = request.cookies.get('access_token')
if not token:
return False
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username: str = payload.get('sub')
if username:
return True
except InvalidTokenError:
return False
return False
async def login(self, request: Request) -> bool:
form = await request.form()
username = form.get('username')
password = form.get('password')
user = authenticate_user(username, password)
if not user:
raise HTTPException(status_code=401, detail="Invalid credentials")
access_token = create_access_token(data={'sub': user['username']})
response = RedirectResponse(url='/admin')
response.set_cookie(key='access_token', value=access_token)
return response
async def logout(self, request: Request) -> bool:
response = RedirectResponse(url='/admin')
response.delete_cookie(key='access_token')
return response
app = FastAPI()
engine = create_async_engine()
authentication_backend = AdminBack(secret_key=SECRET_KEY)
admin = Admin(app, engine, authentication_backend=authentication_backend)
После ввода в форму необходимых данных логина пароля:
метод login отрабатывает корректно (токен создается, объект response возвращается) до момента применения метода set_cookie(). Куки просто не устанавливаются (заголовка Set-cookie не появляется, как и самой куки с токеном), после чего естественно метод authenticate не может достать токен и я снова получаю пустую форму для ввода логина и пароля. При этом в отдельно вынесенном эндпоинте типа:
@app.get('/set/')
async def set_func(request: Request):
token = create_access_token(data={'sub': fake_db['username']})
response = RedirectResponse(url='/admin')
response.set_cookie(key='access_token', value=token)
return response
Все отрабатывает корректно.
В чем может быть причина?
Ответы (1 шт):
Разобрался. методы класса AuthenticationBackend в sqladmin не поддерживают установку кук через set_cookie, зато можно это сделать через работу с сессией:
request.session.update({'access_token':access_token})
Вместо:
async def login(self, request: Request) -> bool:
form = await request.form()
username = form.get('username')
password = form.get('password')
user = authenticate_user(username, password)
if not user:
raise HTTPException(status_code=401, detail="Invalid credentials")
access_token = create_access_token(data={'sub': user['username']})
response = RedirectResponse(url='/admin')
response.set_cookie(key='access_token', value=access_token)
return response
Необходимо прописать:
async def login(self, request: Request) -> bool:
form = await request.form()
username = form.get('username')
password = form.get('password')
user = authenticate_user(username, password)
if not user:
raise HTTPException(status_code=401, detail="Invalid credentials")
access_token = create_access_token(data={'sub': user['username']})
request.session.update({'access_token': access_token})
return True