Есть ли способ получить текущего пользователя из запроса? Я получаю анонимного пользователя, хотя пользователь вошел в систему - PullRequest
2 голосов
/ 21 октября 2019

Это мое первое приложение в django + реакции, поэтому я не профессионал. Я пишу viewset и пытаюсь получить текущего пользователя из запроса, но я получил анонимного пользователя, даже если пользователь вошел в систему. Мой интерфейс работает, и я использую allauth и rest-auth для аутентификации django.

Пожалуйста, помогите!

Я пытался выяснить, есть ли проблема с токеном, но кажется, чтоотлично работает, что. У меня также есть CustomUser, так что, может быть, это ...

Вот мой логин func в реагировать с избыточностью:

export const authLogin = (username, password) => {
    return dispatch => {
        dispatch(authStart());
        axios.post('http://localhost:8000/rest-auth/login/', {
            username: username,
            password: password
        },)
        .then(res => {
            const token = res.data.key;
            const user = username;
            const expirationDate = new Date(new Date().getTime() + 3600 * 1000);
            localStorage.setItem('token', token);
            localStorage.setItem('user', user);
            localStorage.setItem('expirationDate', expirationDate);
            dispatch(authSuccess(token));
            dispatch(checkAuthTimeout(3600));
        })
        .catch(err => {
            dispatch(authFail(err))
        })
    }
}

const authSuccess = (state, action) => {
    return updateObject(state, {
        token: action.token,
        error: null,
        loading: false
    });
}

страница совпадений пользователя для набора просмотра:

import React from "react";
import { Component } from "react";
import { NavLink } from 'react-router-dom';
import axios from 'axios';

class UserMatches extends Component {

    state = {
        matches: null
    }

    componentDidMount() {
        this.getUserMatches()
    }

    getUserMatches = () => {
        const token = `Token ` + localStorage.getItem('token')
        console.log(token)
        const headers = {
            'Authorization': token
        }
        axios.get('http://localhost:8000/matches/api/matches/', {"headers": headers})
        .then(res => {
            console.log(res.data)
            this.setState({
                matches: res.data
            })      
        })
        .catch(err => {
            console.log(err)
        })
    }

    render() {
        const matches = this.state.matches ? 
                        (
                            this.state.matches.map((match) => {
                                const match_link = '/matches/' + match.id + '/'
                                return (
                                    <div>
                                        <div class="divider"></div>
                                        <div class="section">
                                            <h5><NavLink to={match_link}>{match.name}</NavLink></h5>
                                            <p>Date: {match.match_date}</p>
                                            <p>Time: {match.match_time}</p>
                                            <p>Location: {match.location}</p>
                                            <p>Quantity of players: {match.quantity_of_players}</p>
                                            <p>Created by: {match.creator}</p>
                                        </div>
                                    </div>
                                )
                            })
                        )
                        :
                        (
                            <div className="container center">
                                <div class="preloader-wrapper small active">
                                    <div class="spinner-layer spinner-green-only">
                                        <div class="circle-clipper left">
                                            <div class="circle"></div>
                                        </div>
                                        <div class="gap-patch">
                                            <div class="circle"></div>
                                        </div>
                                        <div class="circle-clipper right">
                                            <div class="circle"></div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        )


        return (
            <div className="container">
                {matches}
            </div>
        )
    }
}

export default UserMatches;

а вот мой внешний вид и пользовательская модель:

class MatchViewset(viewsets.ViewSetMixin, generics.ListAPIView):
    serializer_class = MatchSerializer

    def get_queryset(self):
        user = self.request.user
        print(user)
        return Match.objects.filter(creator=user)

class CustomUser(AbstractUser):

    GENDER_CHOICES = (
        ("F", "FAMALE"),
        ("M", "MALE")
    )

    username = models.CharField(blank=False, max_length=255, unique=True)
    first_name = models.CharField(max_length=255, blank=False, default="superuser")
    second_name = models.CharField(max_length=255, blank=False, default="superuser")
    email = models.EmailField(blank=False, unique=True)
    age = models.IntegerField(blank=False, default=18)
    gender = models.CharField(max_length=1, choices=GENDER_CHOICES, blank=True, null=True)
    country = models.CharField(blank=True, null=True, max_length=255)
    city = models.CharField(blank=True, null=True, max_length=255)
    positions = models.ManyToManyField(Position, related_name='positions')
    favourite_team = models.CharField(max_length=255, blank=True, null=True)

    def __str__(self):
        return self.username

У меня также есть адаптер:

class CustomUserAccountAdapter(DefaultAccountAdapter):

    def save_user(self, request, user, form, commit=True):

        user = super().save_user(request, user, form, False)
        user_field(user, 'first_name', request.data.get('firstName'))
        user_field(user, 'second_name', request.data.get('secondName'))
        user_field(user, 'age', request.data.get('age'))
        user.save()
        return user

и настройки:

ACCOUNT_ADAPTER = 'project_football.adapters.CustomUserAccountAdapter'
AUTH_USER_MODEL = 'accounts.CustomUser'

AUTHENTICATION_BACKENDS = (
   "django.contrib.auth.backends.ModelBackend",
   "allauth.account.auth_backends.AuthenticationBackend"
)

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.AllowAny',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
    ),
}

ACCOUNT_EMAIL_REQUIRED = False
ACCOUNT_AUTHENTICATION_METHOD = 'username'
ACCOUNT_EMAIL_VERIFICATION = 'none'

Ответы [ 2 ]

0 голосов
/ 21 октября 2019

Как я вижу, вы используете аутентификацию на основе токенов django rest, и вы не передаете токен в заголовке HTTP-авторизации в своем API-интерфейсе соответствия. При использовании аутентификации на основе токена вы должны передать токен в заголовке HTTP следующим образом:

Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b

Затем ваш запрос будет проходить через класс Tokenauthentication в DRF, и он установит request.user для пользовательского экземпляра, если токен, полученный в заголовке HTTP, действителен.

0 голосов
/ 21 октября 2019

Django рассматривает localhost и 127.0.0.1 как два отдельных домена, и если вы вошли в один, эти данные сеанса недоступны в другом.

Я предполагаю, что вы вошли в localhost а не 127.0.0.1, поэтому вам нужно изменить свои функции так, чтобы они ссылались на домен, в который вошел ваш пользователь:

axios.post('http://localhost:8000/rest-auth/login/ ...
...