Skip to main content
 首页 » 编程设计

python之使用 Django REST 和 OAuth2 在测试脚本中获取 403 响应

2024年10月24日22findumars

我在使用 Django REST 和 OAuth2 的测试脚本中收到 403 响应。我正在使用 force_authenticate。

在 urls.py 中:

urlpatterns = [ 
    url(r'^user-id/$', views.UserIDView.as_view(), name='user-id'), 
    ... 

在 views.py 中:

from oauth2_provider.ext.rest_framework import TokenHasReadWriteScope 
 
class StdPerm(TokenHasReadWriteScope): 
    pass 
 
StdPermClasses = (IsAuthenticated, StdPerm) 
 
class UserIDView(APIView): 
    permission_classes = StdPermClasses 
    renderer_classes = (JSONRenderer,) 
    def get(self, request, format=None): 
        return Response({'id': request.user.id}) 

在测试.py中:

from django.contrib.auth.models import User 
from django.core.urlresolvers import reverse 
from rest_framework import status 
from rest_framework.test import APITestCase 
 
class CreateUserTest(APITestCase): 
    def setUp(self): 
        self.user = User.objects.create_user('daniel', 'daniel@test.com', 
            password='daniel') 
        self.user.save() 
    def test_get_user_id(self): 
        self.client.login(username='daniel', password='daniel') 
        self.client.force_authenticate(user=self.user) 
        response = self.client.get(reverse('user-id')) 
        self.assertEqual(response.status_code, status.HTTP_200_OK) 

通常我使用 curl 没问题:

curl -X GET "http://127.0.0.1:8000/user-id/" -H "Authorization: Bearer b3SlzXlpRSxURyh2BltwdHmhrlqNyt" 

更新 我更改了 test_get_user_id 中的一些行:

    token = Token.objects.create(user=self.user) 
    self.client.force_authenticate(user=self.user, token=token) 

现在我得到错误:

assert False, ('TokenHasScope requires either the' AssertionError:      
TokenHasScope requires either the`oauth2_provider.rest_framework 
.OAuth2Authentication` authentication class to be used. 

请您参考如下方法:

我找到了解决这个问题的方法。基本上我的代码缺少两件事,即 OAuth2 应用程序记录和特定于 OAuth2 的访问 token 。我在设置中添加了以下内容:

app = Application( 
    client_type='confidential', 
    authorization_grant_type='password', 
    name='MyAppTest', 
    user_id=1 
) 
app.save() 

...用于生成合适的访问 token :

app = Application.objects.get(name='MyAppTest') 
token = generate_token() 
expires = now() + timedelta(seconds=oauth2_settings. \ 
    ACCESS_TOKEN_EXPIRE_SECONDS) 
scope = 'read write' 
access_token = AccessToken.objects.create( 
    user=self.user, 
    application=app, 
    expires=expires, 
    token=token, 
    scope=scope 
) 

...然后使用 token :

self.client.force_authenticate(user=self.user, token=access_token) 

导入部分是这样结束的:

from django.contrib.auth.models import User 
from django.core.urlresolvers import reverse 
from rest_framework import status 
from rest_framework.test import APITestCase 
from oauth2_provider.settings import oauth2_settings 
from oauthlib.common import generate_token 
from oauth2_provider.models import AccessToken, Application 
from django.utils.timezone import now, timedelta