django - 有没有办法从请求中获取当前用户?即使用户已登录,我仍收到匿名用户

标签 django reactjs django-rest-framework django-allauth django-rest-auth

这是我在 Django + React 中的第一个应用程序,所以我并不专业。我正在编写 View 集并尝试从请求中获取当前用户,但即使用户已登录,我也得到了匿名用户。我的前端位于 React 中,我正在使用 django-allauthdjango-rest-auth身份验证。

我试图查明 token 是否存在问题,但似乎效果很好。我也有 CustomUser 所以也许是......

这是我在 React 和 Redux 中的登录功能:

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
    });
}

用户匹配 View 集的页面:

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;

这是我的 View 集和自定义用户模型:

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'

最佳答案

正如我所看到的,您正在使用 django Rest 的基于 token 的身份验证,并且您没有在匹配 API 的 HTTP 授权 header 中传递 token 。当使用基于 token 的身份验证时,您必须在 HTTP header 中传递 token ,如下所示:

Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b

那么你的请求将通过DRF的Tokenauthentication类,如果 HTTP header 中收到的 token 有效,它将把 request.user 设置为用户实例。

关于django - 有没有办法从请求中获取当前用户?即使用户已登录,我仍收到匿名用户,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58489988/

相关文章:

mysql - 如果字段存在,Django 过滤查询集

python - 如何在django中使用不同的表注册不同类型的用户?

python - 没有名为 slack 的模块

javascript - 如何以动态方式控制带有悬停(显示和隐藏)的元素

python - django_rest_framwork 发生 "TypeError: ' 链接对象不支持项目分配”

python - 干草堆说 “Model could not be found for SearchResult”

javascript - FunctionComponent HOC 的正确类型

node.js - 从多页面应用程序进行身份验证后,如何在初始下载期间将 JWT token 加载到 React?

python - 即使 is_valid 为 True,Serializer validated_data 也是空的

python - Django:如何在信号处理程序中获取域名