第3部分-OAuth2令牌身份验证

情景

您想要使用 Access Token 根据Django的认证系统对用户进行认证。

设置提供程序

您需要一个功能齐全的OAuth2提供程序,它能够发布访问令牌:只需按照中的步骤操作 the part 1 of the tutorial 。要启用OAuth2令牌身份验证,您需要一个检查请求内部令牌的中间件,以及一个负责令牌验证的自定义身份验证后端。在您的settings.py中:

AUTHENTICATION_BACKENDS = [
    'oauth2_provider.backends.OAuth2Backend',
    # Uncomment following if you want to access the admin
    #'django.contrib.auth.backends.ModelBackend',
    '...',
]

MIDDLEWARE = [
    '...',
    # If you use AuthenticationMiddleware, be sure it appears before OAuth2TokenMiddleware.
    # AuthenticationMiddleware is NOT required for using django-oauth-toolkit.
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'oauth2_provider.middleware.OAuth2TokenMiddleware',
    '...',
]

您可能会使用 django.contrib.auth.backends.ModelBackend 对于OAuth2后端(或者您可能无法登录到管理员),只需注意Django处理身份验证后端的顺序。

如果您将OAuth2后端 after 这个 AuthenticationMiddlewarerequest.user 是有效的,则后端不会执行任何操作;如果 request.user 是匿名用户,它将尝试使用OAuth2访问令牌对用户进行身份验证。

如果您将OAuth2后端 before AuthenticationMiddleware ,或者根本不使用身份验证中间件,它将尝试使用OAuth2访问令牌对用户进行身份验证,并设置 request.userrequest._cached_user 字段,以便身份验证中间件(激活时)不会尝试从会话中获取用户。

如果您使用 AuthenticationMiddleware ,请确保它出现在 OAuth2TokenMiddleware 。然而, AuthenticationMiddleware 不是使用时必需的 django-oauth-toolkit

请注意, OAuth2TokenMiddleware 将用户添加到请求对象。还有一个可选的 OAuth2ExtraTokenMiddleware 这增加了 Token 对这个请求。这使您可以方便地访问 Application 对象在您的视图中。要使用它,只需添加 oauth2_provider.middleware.OAuth2ExtraTokenMiddleware 发送到 MIDDLEWARE 布景。

保护您的视线

身份验证后端将平稳运行,例如, login_required 装饰者,这样你就可以在你的 views.py 模块:

from django.contrib.auth.decorators import login_required
from django.http.response import HttpResponse

@login_required()
def secret_page(request, *args, **kwargs):
    return HttpResponse('Secret contents!', status=200)

要检查一切是否正常运行,请将上面的视图挂载到某个URL:

urlpatterns = [
    path('secret', 'my.views.secret_page', name='secret'),
    '...',
]

你应该有一个 Application 如果您没有注册,请按照前面教程中的步骤创建一个。获得一个 Access Token ,或者遵循应用程序的OAuth2流,或者在Django管理中手动创建。现在假设您的访问令牌值为 123456 您可以尝试访问经过身份验证的视图:

curl -H "Authorization: Bearer 123456" -X GET http://localhost:8000/secret

使用基于REST_框架泛型类的视图

如你已完成 Django REST framework tutorial ,您将熟悉“代码段”示例,特别是SnippetList和SnippetDetail类。

如果能重用这些视图,那就太好了 and 支持令牌处理。解决方案远比这简单得多,而不是将这些类重新编写为基于ProtectedResourceView的。

假设您已经修改了设置,如上所述。关键是设置一个类属性来覆盖默认的 permissions_classes 用一些东西来使用我们的 Access Token 恰到好处。

from oauth2_provider.contrib.rest_framework import TokenHasReadWriteScope

class SnippetList(generics.ListCreateAPIView):
    ...
    permission_classes = [TokenHasReadWriteScope]

class SnippetDetail(generics.ListCreateAPIView):
    ...
    permission_classes = [TokenHasReadWriteScope]

请注意,此示例覆盖Django默认权限类设置。有几种其他方法可以解决这个问题。重写类函数 get_permission_classes 是解决问题的另一种方式。

详细了解 Django REST framework permissions is here.