Как авторизоваться в 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 и создать промежуточное ПО в бэкенде, чтобы прочитать его и получить пользователя из него.

Это может быть удобно, если вы хотите использовать несколько представлений бэкенда, где вам нужно получить данные пользователя.

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