Реализация Django и React с использованием Google OAuth2 не работает с csrftoken

Я реализовал бэкенд Django для процесса авторизации пользователя через Google OAuth2 signin/signup.

Механизм запускается из React UI.

Пользователь может успешно зарегистрироваться, используя бэкенд Django, и я вижу, что связанные пользователи созданы в Django Admin.

Однако, когда я пытаюсь использовать ту же информацию о пользователе через React UI, вызов API "me" не может получить доступ к пользователю Django, который вошел в систему. Но прямой вызов Django через браузер и команду curl работает нормально.

Следующая команда работает нормально с вызовом бэкенда :

curl -X GET --header "Cookie: csrftoken=M1kFFNataWZcbckfdrqUEiXuRRsSRwYKKCH4XvENUyWnLE9xnSMHe7DiaUcDBRU6; sessionid=p156z2d5gy9cwamojxvmxbopg84p99v6" http://localhost:8000/registration/me/

enter image description here

Ниже приведены настройки Django для Cors и CSRF :

CORS_ORIGIN_ALLOW_ALL = True

ALLOWED_HOSTS = ['*']

CORS_ALLOWED_ORIGINS = [
    "http://localhost:3000", 
]

CORS_ALLOW_ALL_ORIGINS=True

CORS_ALLOW_CREDENTIALS = False

CORS_ORIGIN_WHITELIST = [
    'http://localhost:3000'
]

CSRF_COOKIE_NAME = "csrftoken"
CSRF_COOKIE_HTTPONLY = False

CORS_EXPOSE_HEADERS = ["Content-Type", "X-CSRFToken"]
CORS_ALLOW_CREDENTIALS = True

CSRF_COOKIE_AGE = None
CSRF_COOKIE_DOMAIN = 'localhost'
CSRF_COOKIE_HTTPONLY = True
CSRF_COOKIE_SECURE = True
CSRF_USE_SESSIONS = True

Ниже приведены остальные настройки фреймворка :

REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',),

    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ),
    'DEFAULT_PERMISSIONS_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    )
}

Вызов API от Django для "меня" :

@api_view(['GET'])
def current_user(request):
    from rest_framework.permissions import IsAuthenticated
    permission_classes = [IsAuthenticated]
    user = request.user
    if user.is_authenticated:
        return Response({
            'username'       : user.username,
            'email'          : user.email,
            'firstname'      : user.first_name,
            'lastname'       : user.last_name,
            'picture'        : user.picture,
            'email_verified' : user.email_verified,
            'locale'         : user.locale,
            'token'          : user.token
        })

    return Response({'user' : 'anonymous'})

Ниже приводится звонок Axios :

function getCookie(name) {
    var cookieValue = null;

    if (document.cookie && document.cookie !== '') {
        console.log("COOKIE : " + document.cookie);
        var cookieValue = document.cookie
    }
    return cookieValue;
}

var csrftoken = getCookie('csrftoken').split("=")[1];
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";
axios.defaults.xsrfCookieName = "csrftoken";

axios({
        method: 'get',
        url: 'http://localhost:8000/registration/me/',
        data: {
                csrfmiddlewaretoken: csrftoken,
                'Authentication' : "Token " + csrftoken,
              },
        headers: {
                "Content-Type": "X-CSRFToken",
                'X-CSRFTOKEN' : "M1kFFNataWZcbckfdrqUEiXuRRsSRwYKKCH4XvENUyWnLE9xnSMHe7DiaUcDBRU6",
                },
        withCredentials: false,
        xsrfHeaderName: 'X-CSRFToken',
        xsrfCookieName: 'csrftoken',
    }).then(res => {
        resultState.state = 'success';
        resultState.data = res.data;

        console.log("registration/me success : " + JSON.stringify(resultState.data));
    }).catch((err) => {
        resultState.state = 'error';
        resultState.data['message'] = err.message;

        console.log("registration/me error : " + JSON.stringify(resultState.data));
    })

Реакция на вызов Django выглядит следующим образом :

registration/me success : {"user":"anonymous"}

Я могу предоставить любую дополнительную информацию о настройке. Любые предложения будут оценены по достоинству.

На самом деле все необходимое было на месте, достаточно было только установить параметр "withCredentials : true". Страница уже знала cookie / связанного пользователя, но axios не использовал информацию cookie автоматически.

Добавление параметра, как указано ниже, было достаточным :

axios({
    method: 'get',
    url: 'http://localhost:8000/registration/me/',
    withCredentials: true,
}).then(res => {
    resultState.state = 'success';
    resultState.data = res.data;
}).catch((err) => {
    resultState.state = 'error';
    resultState.data['message'] = err.message;
})
Вернуться на верх