简体   繁体   English

带有 oAuth2 的 Django DRF 使用 DOT (django-oauth-toolkit)

[英]Django DRF with oAuth2 using DOT (django-oauth-toolkit)

I am trying to make DRF work with oAuth2 (django-oauth-toolkit).我正在尝试使 DRF 与 oAuth2 (django-oauth-toolkit) 一起使用。

I was focusing on http://httplambda.com/a-rest-api-with-django-and-oauthw-authentication/我专注于http://httplambda.com/a-rest-api-with-django-and-oauthw-authentication/

First I followed that instruction, but later, after getting authentication errors, I setup this demo: https://github.com/felix-d/Django-Oauth-Toolkit-Python-Social-Auth-Integration首先,我遵循了该说明,但后来,在遇到身份验证错误后,我设置了此演示: https : //github.com/felix-d/Django-Oauth-Toolkit-Python-Social-Auth-Integration

Result was the same: I couldn't generate access token using this curl:结果是一样的:我无法使用此 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/

I got this error:我收到此错误:

{"error": "unsupported_grant_type"}

The oAuth2 application was set with grant_type password. oAuth2 应用程序设置了 grant_type 密码。 I changed grant_type to "client credentials" and tried this curl:我将 grant_type 更改为“客户端凭据”并尝试了此卷曲:

curl -X POST -d "grant_type=client_credentials" -u "<client_id>:<client_secret>" http://127.0.0.1:8000/o/token/

This worked and I got generated auth token.这有效,我得到了生成的身份验证令牌。

After that I tried to get a list of all beers:之后,我尝试获取所有啤酒的列表:

curl -H "Authorization: Bearer <auth_token>" http://127.0.0.1:8000/beers/

And I got this response:我得到了这样的回应:

{"detail":"You do not have permission to perform this action."}

This is the content of views.py that should show the beers:这是应该显示啤酒的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)

I am not sure what can be the problem here.我不确定这里有什么问题。 First with "unsuported grant type" and later with other curl call.首先使用“不受支持的授权类型”,然后使用其他 curl 调用。 This also happen to me when I did basic tutorial from django-oauth-toolkit.当我从 django-oauth-toolkit 做基本教程时,这也发生在我身上。 I am using Django 1.8.2 and python3.4我正在使用 Django 1.8.2 和 python3.4

Thanks for all help!感谢所有帮助!

My settings.py looks like this我的 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'}
}

I have tried the demo you mentioned and everything was fine.我试过你提到的演示,一切都很好。

$ 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/
[]

In your case, I think, you have created an application with wrong "Authorization grant type" .在您的情况下,我认为您创建了一个具有错误"Authorization grant type"的应用程序。

Use this application settings:使用此应用程序设置:

Name: just a name of your choice
Client Type: confidential
Authorization Grant Type: Resource owner password-based

This https://django-oauth-toolkit.readthedocs.org/en/latest/rest-framework/getting_started.html#step-3-register-an-application helped me a lot.这个https://django-oauth-toolkit.readthedocs.org/en/latest/rest-framework/getting_started.html#step-3-register-an-application帮助了我很多。

Here the database file I've created: https://www.dropbox.com/s/pxeyphkiy141i1l/db.sqlite3.tar.gz?dl=0这里是我创建的数据库文件: https : //www.dropbox.com/s/pxeyphkiy141i1l/db.sqlite3.tar.gz?dl=0

You can try it yourself.你可以自己试试。 No source code changed at all.根本没有更改源代码。 Django admin username - superuser, password - 123qwe. Django 管理员用户名 - 超级用户,密码 - 123qwe。

When you use "client credentials" it doesn't set the user on the generated access token, this is the root of that you do not have permission error you are seeing.当您使用“客户端凭据”时,它不会在生成的访问令牌上设置用户,这是您看到的you do not have permission错误的根源。

When using the client credentials grant type, you need to set the Rest Framework permission handler to look at tokens as client credentials does not set the user on the generated token.使用client credentials授予类型时,您需要设置 Rest Framework 权限处理程序以查看令牌,因为client credentials不会在生成的令牌上设置用户。 Django OAuth Toolkit provides custom permissions for this purpose: Django OAuth Toolkit 为此提供自定义权限:

https://django-oauth-toolkit.readthedocs.org/en/latest/rest-framework/permissions.html https://django-oauth-toolkit.readthedocs.org/en/latest/rest-framework/permissions.html

Or if your entire API is subject to the same type of permissions you can just set the permission handler globally in your settings.py file, for example:或者,如果您的整个 API 受到相同类型的权限的约束,您只需在settings.py文件中全局设置权限处理程序,例如:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'oauth2_provider.ext.rest_framework.OAuth2Authentication',
    ),

    'DEFAULT_PERMISSION_CLASSES': (
        'oauth2_provider.ext.rest_framework.TokenHasReadWriteScope',
    )
}

This assumes of course that you grant read write permissions at the time.这当然假设您当时授予read write权限。

More info about scopes here:关于范围的更多信息在这里:

https://django-oauth-toolkit.readthedocs.org/en/latest/settings.html https://django-oauth-toolkit.readthedocs.org/en/latest/settings.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM