Как авторизоваться в Django backend при авторизации в ReactJs frontend?
Я делаю веб-приложение с Django 3.2 (Python 9) в качестве бэкенда и ReactJs 17 в качестве фронтенда с Graphene(GraphQL) API между ними. ReactJs использует Apollo Client Provider 3.4 для выполнения API запросов и мутаций.
Я использую пакет django-graphql-auth
для аутентификации пользователей и храню токен аутентификации пользователя в localStorage браузера, который затем помещаю в заголовки Apollo Provider.
Все работает хорошо до этого момента.
Теперь проблема заключается в том, что пользователь должен иметь возможность скачивать файлы, нажав на ссылку во фронтенде. Эта ссылка будет перенаправлять на бэкенд Django view, где файл будет помещен в HttpResponse
. Пользователю будет предложено согласиться на загрузку файла.
Однако файл генерируется на основе пользователя, который его запрашивает (точнее, на основе группы пользователя). Поэтому в моем представлении Django я использую переменную request.user.groups
для генерации файла, который будет загружен.
Вот в чем проблема: на стороне бэкенда пользователь остается анонимным, хотя аутентифицирован во фронтенде.
Как я могу аутентифицировать пользователя в бэкенде, когда (он) входит во фронтенд?
Могу ли я просто передать значение request.user
из React в представление загрузки Django? Если да, то как это возможно?
Заранее спасибо за помощь.
Я нашел решение.
Я просто включаю токен аутентификации JWT пользователя в url, указывающий на представление бэкенда.
# urls
from django.urls import path
from src import views
urlpatters = [
path("download/<str:user_auth_token>/", views.my_view),
]
Мое представление Django в бэкенде затем получает пользователя из полезной нагрузки токена. Если токен недействителен, возникает ошибка.
from graphql_jwt.utils import get_payload, get_user_by_payload
from src.models import AppUser
def get_user_from_token(jwt_token: str) -> AppUser:
"""Get the user from the JWT token received from the frontend"""
return get_user_by_payload(get_payload(jwt_token))
Итак, пользователь по-прежнему не аутентифицирован в бэкенде. Я получаю пользователя не из request
, а из токена:
# view
from django.core.handlers.wsgi import WSGIRequest
def my_view(request: WSGIRequest, user_auth_token: str):
user = get_user_from_token(user_auth_token)
# Do something...
Мне это нужно только в одном представлении, но я видел, что вместо отправки токена через url, я могу поместить его в cookie и создать промежуточное ПО в бэкенде, чтобы прочитать его и получить пользователя из него.
Это может быть удобно, если вы хотите использовать несколько представлений бэкенда, где вам нужно получить данные пользователя.