使用 DOT 的带有 oAuth2 的 Django DRF (django-oauth-toolkit)
Django DRF with oAuth2 using DOT (django-oauth-toolkit)
我正在尝试使 DRF 与 oAuth2 (django-oauth-toolkit) 一起工作。
我关注的是http://httplambda.com/a-rest-api-with-django-and-oauthw-authentication/
首先我按照该说明进行操作,但后来,在出现身份验证错误后,我设置了这个演示:https://github.com/felix-d/Django-Oauth-Toolkit-Python-Social-Auth-Integration
结果相同:我无法使用此 curl 生成访问令牌:
curl -X POST -d "grant_type=password&username=<user_name>&password=<password>" -u "<client_id>:<client_secret>" http://127.0.0.1:8000/o/token/
我收到这个错误:
{"error": "unsupported_grant_type"}
oAuth2 应用程序设置了 grant_type 密码。我将 grant_type 更改为 "client credentials" 并尝试了这个卷曲:
curl -X POST -d "grant_type=client_credentials" -u "<client_id>:<client_secret>" http://127.0.0.1:8000/o/token/
这成功了,我得到了生成的授权令牌。
之后我试图获取所有啤酒的列表:
curl -H "Authorization: Bearer <auth_token>" http://127.0.0.1:8000/beers/
我得到了这样的回复:
{"detail":"You do not have permission to perform this action."}
这是 views.py 应该显示啤酒的内容:
from beers.models import Beer
from beers.serializer import BeerSerializer
from rest_framework import generics, permissions
class BeerList(generics.ListCreateAPIView):
serializer_class = BeerSerializer
permission_classes = (permissions.IsAuthenticated,)
def get_queryset(self):
user = self.request.user
return Beer.objects.filter(owner=user)
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
我不确定这里的问题是什么。首先使用 "unsuported grant type" ,然后使用其他 curl 调用。当我从 django-oauth-toolkit 做基本教程时,这也发生在我身上。我正在使用 Django 1.8.2 和 python3.4
感谢大家的帮助!
我的settings.py看起来像这样
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
SECRET_KEY = 'hd#x!ysy@y+^*%i+klb)o0by!bh&7nu3uhg+5r0m=x$a!j@9'
DEBUG = True
TEMPLATE_DEBUG = True
ALLOWED_HOSTS = []
TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.auth.context_processors.auth',
)
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'oauth2_provider',
'rest_framework',
'beers',
)
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
)
ROOT_URLCONF = 'beerstash.urls'
WSGI_APPLICATION = 'beerstash.wsgi.application'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
STATIC_URL = '/static/'
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'oauth2_provider.ext.rest_framework.OAuth2Authentication',
)
}
OAUTH2_PROVIDER = {
# this is the list of available scopes
'SCOPES': {'read': 'Read scope', 'write': 'Write scope'}
}
我试过你提到的演示,一切正常。
$ curl -X POST -d "grant_type=password&username=superuser&assword=123qwe" -u"xLJuHBcdgJHNuahvER9pgqSf6vcrlbkhCr75hTCZ:nv9gzOj0BMf2cdxoxsnYZuRYTK5QwpKWiZc7USuJpm11DNtSE9X6Ob9KaVTKaQqeyQZh4KF3oZS4IJ7o9n4amzfqKJnoL7a2tYQiWgtYPSQpY6VKFjEazcqSacqTx9z8" http://127.0.0.1:8000/o/token/
{"access_token": "jlLpKwzReB6maEnjuJrk2HxE4RHbiA", "token_type": "Bearer", "expires_in": 36000, "refresh_token": "DsDWz1LiSZ3bd7NVuLIp7Dkj6pbse1", "scope": "read write groups"}
$ curl -H "Authorization: Bearer jlLpKwzReB6maEnjuJrk2HxE4RHbiA" http://127.0.0.1:8000/beers/
[]
我认为,就您而言,您创建的应用程序 “授权授予类型”.
使用此应用程序设置:
Name: just a name of your choice
Client Type: confidential
Authorization Grant Type: Resource owner password-based
这里是我创建的数据库文件:https://www.dropbox.com/s/pxeyphkiy141i1l/db.sqlite3.tar.gz?dl=0
你可以自己试试。根本没有更改源代码。
Django 管理员用户名 - 超级用户,密码 - 123qwe.
当您使用 "client credentials" 时,它不会在生成的访问令牌上设置用户,这是您看到的 you do not have permission
错误的根源。
使用 client credentials
授权类型时,您需要设置 Rest Framework 权限处理程序以查看令牌,因为 client credentials
不会在生成的令牌上设置用户。 Django OAuth Toolkit 为此目的提供自定义权限:
https://django-oauth-toolkit.readthedocs.org/en/latest/rest-framework/permissions.html
或者如果您的整个 API 都受制于相同类型的权限,您可以在 settings.py
文件中全局设置权限处理程序,例如:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'oauth2_provider.ext.rest_framework.OAuth2Authentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'oauth2_provider.ext.rest_framework.TokenHasReadWriteScope',
)
}
这当然假设您当时授予 read write
权限。
有关范围的更多信息:
https://django-oauth-toolkit.readthedocs.org/en/latest/settings.html
我正在尝试使 DRF 与 oAuth2 (django-oauth-toolkit) 一起工作。
我关注的是http://httplambda.com/a-rest-api-with-django-and-oauthw-authentication/
首先我按照该说明进行操作,但后来,在出现身份验证错误后,我设置了这个演示:https://github.com/felix-d/Django-Oauth-Toolkit-Python-Social-Auth-Integration
结果相同:我无法使用此 curl 生成访问令牌:
curl -X POST -d "grant_type=password&username=<user_name>&password=<password>" -u "<client_id>:<client_secret>" http://127.0.0.1:8000/o/token/
我收到这个错误:
{"error": "unsupported_grant_type"}
oAuth2 应用程序设置了 grant_type 密码。我将 grant_type 更改为 "client credentials" 并尝试了这个卷曲:
curl -X POST -d "grant_type=client_credentials" -u "<client_id>:<client_secret>" http://127.0.0.1:8000/o/token/
这成功了,我得到了生成的授权令牌。
之后我试图获取所有啤酒的列表:
curl -H "Authorization: Bearer <auth_token>" http://127.0.0.1:8000/beers/
我得到了这样的回复:
{"detail":"You do not have permission to perform this action."}
这是 views.py 应该显示啤酒的内容:
from beers.models import Beer
from beers.serializer import BeerSerializer
from rest_framework import generics, permissions
class BeerList(generics.ListCreateAPIView):
serializer_class = BeerSerializer
permission_classes = (permissions.IsAuthenticated,)
def get_queryset(self):
user = self.request.user
return Beer.objects.filter(owner=user)
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
我不确定这里的问题是什么。首先使用 "unsuported grant type" ,然后使用其他 curl 调用。当我从 django-oauth-toolkit 做基本教程时,这也发生在我身上。我正在使用 Django 1.8.2 和 python3.4
感谢大家的帮助!
我的settings.py看起来像这样
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
SECRET_KEY = 'hd#x!ysy@y+^*%i+klb)o0by!bh&7nu3uhg+5r0m=x$a!j@9'
DEBUG = True
TEMPLATE_DEBUG = True
ALLOWED_HOSTS = []
TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.auth.context_processors.auth',
)
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'oauth2_provider',
'rest_framework',
'beers',
)
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
)
ROOT_URLCONF = 'beerstash.urls'
WSGI_APPLICATION = 'beerstash.wsgi.application'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
STATIC_URL = '/static/'
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'oauth2_provider.ext.rest_framework.OAuth2Authentication',
)
}
OAUTH2_PROVIDER = {
# this is the list of available scopes
'SCOPES': {'read': 'Read scope', 'write': 'Write scope'}
}
我试过你提到的演示,一切正常。
$ curl -X POST -d "grant_type=password&username=superuser&assword=123qwe" -u"xLJuHBcdgJHNuahvER9pgqSf6vcrlbkhCr75hTCZ:nv9gzOj0BMf2cdxoxsnYZuRYTK5QwpKWiZc7USuJpm11DNtSE9X6Ob9KaVTKaQqeyQZh4KF3oZS4IJ7o9n4amzfqKJnoL7a2tYQiWgtYPSQpY6VKFjEazcqSacqTx9z8" http://127.0.0.1:8000/o/token/
{"access_token": "jlLpKwzReB6maEnjuJrk2HxE4RHbiA", "token_type": "Bearer", "expires_in": 36000, "refresh_token": "DsDWz1LiSZ3bd7NVuLIp7Dkj6pbse1", "scope": "read write groups"}
$ curl -H "Authorization: Bearer jlLpKwzReB6maEnjuJrk2HxE4RHbiA" http://127.0.0.1:8000/beers/
[]
我认为,就您而言,您创建的应用程序 “授权授予类型”.
使用此应用程序设置:
Name: just a name of your choice
Client Type: confidential
Authorization Grant Type: Resource owner password-based
这里是我创建的数据库文件:https://www.dropbox.com/s/pxeyphkiy141i1l/db.sqlite3.tar.gz?dl=0
你可以自己试试。根本没有更改源代码。 Django 管理员用户名 - 超级用户,密码 - 123qwe.
当您使用 "client credentials" 时,它不会在生成的访问令牌上设置用户,这是您看到的 you do not have permission
错误的根源。
使用 client credentials
授权类型时,您需要设置 Rest Framework 权限处理程序以查看令牌,因为 client credentials
不会在生成的令牌上设置用户。 Django OAuth Toolkit 为此目的提供自定义权限:
https://django-oauth-toolkit.readthedocs.org/en/latest/rest-framework/permissions.html
或者如果您的整个 API 都受制于相同类型的权限,您可以在 settings.py
文件中全局设置权限处理程序,例如:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'oauth2_provider.ext.rest_framework.OAuth2Authentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'oauth2_provider.ext.rest_framework.TokenHasReadWriteScope',
)
}
这当然假设您当时授予 read write
权限。
有关范围的更多信息:
https://django-oauth-toolkit.readthedocs.org/en/latest/settings.html