我的测试脚本中有403响应,它使用Django REST和OAuth2。我正在使用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})
在tests.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 -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.
答案 0 :(得分:2)
我找到了解决这个问题的方法。基本上我的代码缺少两件事,即OAuth2应用程序记录和特定于OAuth2的访问令牌。我在setUp中添加了以下内容:
app = Application(
client_type='confidential',
authorization_grant_type='password',
name='MyAppTest',
user_id=1
)
app.save()
...用于生成合适的访问令牌:
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
)
...然后使用令牌:
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
答案 1 :(得分:0)
这对我有用
from oauth2_provider.settings import oauth2_settings
from oauth2_provider.models import get_access_token_model,
get_application_model
from django.contrib.auth import get_user_model
from django.utils import timezone
from rest_framework.test import APITestCase
Application = get_application_model()
AccessToken = get_access_token_model()
UserModel = get_user_model()
class Test_mytest(APITestCase):
def setUp(self):
oauth2_settings._SCOPES = ["read", "write", "scope1", "scope2", "resource1"]
self.test_user = UserModel.objects.create_user("test_user", "test@example.com", "123456")
self.application = Application.objects.create(
name="Test Application",
redirect_uris="http://localhost http://example.com http://example.org",
user=self.test_user,
client_type=Application.CLIENT_CONFIDENTIAL,
authorization_grant_type=Application.GRANT_AUTHORIZATION_CODE,
)
self.access_token = AccessToken.objects.create(
user=self.test_user,
scope="read write",
expires=timezone.now() + timezone.timedelta(seconds=300),
token="secret-access-token-key",
application=self.application
)
# read or write as per your choice
self.access_token.scope = "read"
self.access_token.save()
# correct token and correct scope
self.auth = "Bearer {0}".format(self.access_token.token)
def test_success_response(self):
url = reverse('my_url',)
# Obtaining the POST response for the input data
response = self.client.get(url, HTTP_AUTHORIZATION=self.auth)
# checking wether the response is success
self.assertEqual(response.status_code, status.HTTP_200_OK)
现在一切都会按预期工作。感谢