【问题标题】:Django DRF with oAuth2 using DOT (django-oauth-toolkit)Django DRF 与 oAuth2 使用 DOT (django-oauth-toolkit)
【发布时间】:2015-08-31 14:06:02
【问题描述】:

我正在尝试使 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 更改为“客户端凭据”并尝试了这个 curl:

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)

我不确定这里有什么问题。首先是“不受支持的授权类型”,然后是其他 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=$3x$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'}
}

【问题讨论】:

  • 您的设置是什么样的?您是否添加了 oauth 的所有设置以用作 REST Framework API 身份验证?
  • @AlexT 我添加了我的 settings.py 文件
  • 较新版本使用:from oauth2_provider.contrib.rest_framework import OAuth2Authentication

标签: python django django-rest-framework


【解决方案1】:

我已经尝试过你提到的演示,一切都很好。

$ 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://django-oauth-toolkit.readthedocs.org/en/latest/rest-framework/getting_started.html#step-3-register-an-application对我帮助很大。

这里是我创建的数据库文件:https://www.dropbox.com/s/pxeyphkiy141i1l/db.sqlite3.tar.gz?dl=0

你可以自己试试。根本没有改变源代码。 Django 管理员用户名 - 超级用户,密码 - 123qwe。

【讨论】:

  • 嗨 Yevgeniy,感谢您的回答 - 我会对其进行测试并回复您!
  • 我再次测试了它 - 使用您所说的设置并且它正在工作!感谢您指出这一点!
【解决方案2】:

当您使用“客户端凭据”时,它不会在生成的访问令牌上设置用户,这是您看到的 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.pyfile 中全局设置权限处理程序,例如:

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

【讨论】:

  • 对于更新版本的替换 'oauth2_provider.ext.rest_framework.OAuth2Authentication' 与 'oauth2_provider.contrib.rest_framework.OAuth2Authentication' 和 'oauth2_provider.ext.rest_framework.TokenHasReadWriteScope' 与 'oauth2_provider.contrib.rest_framework .TokenHasReadWriteScope',
猜你喜欢
  • 2019-01-20
  • 1970-01-01
  • 1970-01-01
  • 2020-12-11
  • 1970-01-01
  • 2021-05-08
  • 2021-09-15
  • 2021-04-28
  • 2014-11-04
相关资源
最近更新 更多