【问题标题】:request.user in DRF Views vs Django ViewsDRF 视图与 Django 视图中的 request.user
【发布时间】:2019-06-03 10:29:49
【问题描述】:

我正在尝试在 API 中获取经过身份验证的用户。这是代码:-

DRF 视图

from braces.views import CsrfExemptMixin
from rest_framework import generics

class API(CsrfExemptMixin, generics.CreateAPIView):
    authentication_classes = []
    serializer_class = SomeSerializer

    def post(self, request):
        print(request.user.id)  # None

Django 视图

from django.views import View
from braces.views import CsrfExemptMixin

class API(CsrfExemptMixin, View):
    authentication_classes = []

    def post(self, request):
        print(request.user.id)  # prints id of the user.

为什么我在 2 种不同的情况下得到不同的响应?以下是我的设置。

AUTHENTICATION_BACKENDS = (
    # Needed to login by username in Django admin, regardless of `allauth`
    'django.contrib.auth.backends.ModelBackend',

    # `allauth` specific authentication methods, such as login by e-mail
    'allauth.account.auth_backends.AuthenticationBackend',

    # Needed to login by email
    'modules.profile.backend.EmailBackend'
)


REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
    'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',),
    'EXCEPTION_HANDLER': 'modules.utils.exception_handler.custom_exception_handler',
    'PAGE_SIZE': 10,
}

【问题讨论】:

  • 您可以添加CsrfExemptMixin 引用吗?
  • 完成。请检查。
  • 您的 Django 会话是如何配置的?您如何对此进行测试,即用于进行这些调用的前端是什么?应该没有区别。
  • 我的前端是一个 Chrome 扩展程序,它在我的 POST 端点上触发跨域请求。
  • @PythonEnthusiast print(request.user) 的输出是什么?

标签: django django-rest-framework


【解决方案1】:

您尚未定义任何身份验证后端供 DRF 使用。您应该在视图中指定它:

from rest_framework.authentication import SessionAuthentication

class API(CsrfExemptMixin, generics.CreateAPIView):
    authentication_classes = [SessionAuthentication]

或者从视图中完全删除 authentication_classes 并在您的 REST_FRAMEWORK 设置中添加 SessionAuthentication 后端:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.SessionAuthentication',
    ),
    ...
}

【讨论】:

  • 我故意将authentication_classes 留空。否则它会抛出 CSRF Failed: CSRF token missing or incorrect.
  • 我将authentication_classes 设置为空列表,并按照您的建议在设置中添加了DEFAULT_AUTHENTICATION_CLASSES。还是一样的反应。 DRF 打印 AnonymousUser,其中 Django View 打印 username
  • 是的,因为您覆盖了默认值,有效地禁用了该视图的身份验证。如果您不进行身份验证,那么没有经过身份验证的用户 ID 也就不足为奇了。无论如何,身份验证与 CSRF 保护毫无关系。请注意,默认情况下 DRF 视图不会强制执行 CSRF 保护,因此您不需要使用该豁免 mixin。
  • 我完全理解身份验证与 CSRF 令牌无关。但是,如果按照您的建议添加 SessionAuthentication,我将如何解决 csrf 问题?
  • 使用 SessionAuthentication 执行状态更改操作(post/put/patch)时需要 CSRF 令牌。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-09
  • 1970-01-01
相关资源
最近更新 更多