Django oauth2请求中request.user返回AnonymousUser

6

我是一名Django新手,正在尝试创建一个API,以便iOS客户端使用后端。目前,我正在使用curl测试我的API访问。

我已成功生成了访问令牌,方法如下:

curl -X POST -d "grant_type=password&username=example_user&password=example_password" http://clientID:clientSecret@localhost:8000/o/token/

生成了以下响应 -
{
    "access_token": "oAyNlYuGVk1Sr8oO1EsGnLwOTL7hAY", 
    "scope": "write read", 
    "expires_in": 36000, 
    "token_type": "Bearer", 
    "refresh_token": "pxd5rXzz1zZIKEtmqPgE608a4H9E5m"
}

我随后使用访问令牌尝试访问以下类视图:
from django.http import JsonResponse
from oauth2_provider.views.generic import ProtectedResourceView
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator

class post_test(ProtectedResourceView):

    def get(self, request, *args, **kwargs):
        print(request.user)
        return JsonResponse({'Message': "You used a GET request"})

    def post(self, request, *args, **kwargs):
        print(request.user)
        return JsonResponse({'Message': 'You used a POST request'})

    @method_decorator(csrf_exempt)
    def dispatch(self, *args, **kwargs):
        return super(post_test, self).dispatch(*args, **kwargs)

使用以下curl请求:

curl -H "Authorization: Bearer oAyNlYuGVk1Sr8oO1EsGnLwOTL7hAY" -X GET http://localhost:8000/api/post-test/

以下是适当的响应客户端的方式:

{"Message": "You used a GET request"}

但是在控制台中,我期望看到request.user变量,但实际上我看到的是AnonymousUser

这个令牌不应该分配给example_user吗?request.user不应该返回这个吗?


1
你能解决这个问题吗? - Nikko R.
不幸的是,目前我正在使用一种解决方法:将用户名插入POST和GET参数列表中。 - jhc
@jhc,你还在使用临时解决方案吗?你最终找到解决办法了吗? - Emmanuel Murairi
3个回答

3

request.user 返回AnonymousUser,因为您在此处使用的访问令牌未与任何用户关联。

从文档中可以看到: 当您使用/o/token/端点生成访问令��时,它不会自动将令牌与用户关联起来。它只会验证提供的凭据,并在凭据为真且有效时生成访问令牌。令牌本身不携带有关用户是谁的信息。

安装Django REST Framework后,在属性字段中添加Auth:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
    ],
}

运行:python manage.py drf_create_token <这里填写用户名>

现在是 post_test 视图:

from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView
from rest_framework.authentication import TokenAuthentication
from django.http import JsonResponse

class post_test(APIView):
    auth_cls = [TokenAuthentication]
    perm_cls = [IsAuthenticated]

    def get(self, request, *args, **kwargs):
        user = request.user
        print(user) 
        return JsonResponse({'Message': "You used a GET request"})

    def post(self, request, *args, **kwargs):
        user = request.user
        print(user)
        return JsonResponse({'Message': 'You used a POST request'})

希望这对你有所帮助!

0

我已经测试了你的代码片段,它在我的端上运行正常。我可以通过request.user获取用户。

你很可能缺少一些配置,特别是MiddlewareAUTHENTICATION_BACKENDS

AUTHENTICATION_BACKENDS = [
    'oauth2_provider.backends.OAuth2Backend',
    # Uncomment following if you want to access the admin
    #'django.contrib.auth.backends.ModelBackend',
    '...',
]

MIDDLEWARE = [
    '...',
    # If you use AuthenticationMiddleware, be sure it appears before OAuth2TokenMiddleware.
    # AuthenticationMiddleware is NOT required for using django-oauth-toolkit.
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'oauth2_provider.middleware.OAuth2TokenMiddleware',
    '...',
]
你可以在这里阅读更多信息: https://django-oauth-toolkit.readthedocs.io/en/latest/tutorial/tutorial_03.html 如果还是不起作用,请告诉我,我会再次检查代码片段。

-1

使用request.resource_owner代替request.user

Django OAuth Toolkit区分与Bearer Token关联的用户和与请求附加的任何其他Django身份验证相关联的用户。具体来说,ProtectedResourceView包括ProtectedResourceMixin的行为,其中包括以下调度方法:

def dispatch(self, request, *args, **kwargs):
    # let preflight OPTIONS requests pass
    if request.method.upper() == "OPTIONS":
        return super().dispatch(request, *args, **kwargs)

    # check if the request is valid and the protected resource may be accessed
    valid, r = self.verify_request(request)
    if valid:
        request.resource_owner = r.user
        return super().dispatch(request, *args, **kwargs)
    else:
        return HttpResponseForbidden()

我有同样的问题,而这并不能解决它。 - Emmanuel Murairi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接