Authentication - Django REST framework

身份验证-Django REST框架

authentication.py

认证

奥斯需要是可插拔的。

雅各布·卡普兰-莫斯“休息最坏的做法”

身份验证是将传入的请求与一组标识凭证相关联的机制,例如请求来自的用户或与其签名的令牌。这个许可节流然后,策略可以使用这些凭据来确定是否应该允许请求。

REST框架提供了许多开箱即用的身份验证方案,还允许您实现自定义方案。

身份验证总是在视图开始时,在权限和节流检查发生之前,以及在允许进行任何其他代码之前运行。

这个request.user属性通常设置为contrib.auth包裹的User班级,等级。

这个request.auth属性用于任何其他身份验证信息,例如,它可用于表示与请求签名的身份验证令牌。


注:别忘了身份验证本身不允许或不允许传入请求,它仅标识请求使用的凭据。

有关如何为API设置权限策略的信息,请参阅权限文档.


如何确定身份验证

身份验证方案总是定义为类的列表。REST框架将尝试使用列表中的每个类进行身份验证,并将request.userrequest.auth使用成功身份验证的第一个类的返回值。

如果没有类认证,request.user将被设置为django.contrib.auth.models.AnonymousUser,和request.auth将被设置为None.

价值request.userrequest.auth对于未经身份验证的请求,可以使用UNAUTHENTICATED_USERUNAUTHENTICATED_TOKEN设置。

设置身份验证方案

默认身份验证方案可以全局设置,使用DEFAULT_AUTHENTICATION_CLASSES背景。例如。

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ]
}

还可以使用APIView基于类的视图。

from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

class ExampleView(APIView):
    authentication_classes = [SessionAuthentication, BasicAuthentication]
    permission_classes = [IsAuthenticated]

    def get(self, request, format=None):
        content = {
            'user': unicode(request.user),  # `django.contrib.auth.User` instance.
            'auth': unicode(request.auth),  # None
        }
        return Response(content)

或者,如果您使用的是@api_view具有基于功能的视图的装饰器。

@api_view(['GET'])
@authentication_classes([SessionAuthentication, BasicAuthentication])
@permission_classes([IsAuthenticated])
def example_view(request, format=None):
    content = {
        'user': unicode(request.user),  # `django.contrib.auth.User` instance.
        'auth': unicode(request.auth),  # None
    }
    return Response(content)

未经许可和禁止的反应

当未经身份验证的请求被拒绝权限时,可能会出现两个不同的错误代码。

HTTP 401响应必须始终包括WWW-Authenticate标头,指示客户端如何进行身份验证。http 403响应不包括WWW-Authenticate头球。

将使用的响应类型取决于身份验证方案。虽然可以使用多个认证方案,但只能使用一个方案来确定响应的类型。在确定响应类型时,将使用视图上的第一个身份验证类。.

注意,当请求可以成功地进行身份验证,但仍被拒绝执行请求的权限时,在这种情况下,403 Permission Denied无论身份验证方案如何,都将始终使用响应。

ApacheMOD_WSGI特定配置

注意,如果部署到Apache使用mod_wSGi默认情况下,授权头不会传递给WSGI应用程序,因为它假定身份验证将由Apache处理,而不是在应用程序级别处理。

如果您正在部署到Apache,并且使用任何基于非会话的身份验证,则需要显式配置mod_wSGi以将所需的标头传递给应用程序。这可以通过指定WSGIPassAuthorization指令,并将其设置为'On'.

# this can go in either server config, virtual host, directory or .htaccess
WSGIPassAuthorization On

API参考

基本认证

此身份验证方案使用HTTP基本身份验证,根据用户的用户名和密码签名。基本身份验证通常只适用于测试。

如果鉴定成功,基本认证提供下列凭据。

  • request.user将是一个DjangoUser举个例子。
  • request.auth将是None.

被拒绝权限的未经身份验证的响应将导致HTTP 401 Unauthorized使用适当的WWW-身份验证头进行响应。例如:

WWW-Authenticate: Basic realm="api"

注:如果你用基本认证在生产中,必须确保api只在https...您还应该确保您的API客户端在登录时总是重新请求用户名和密码,并且永远不会将这些细节存储到持久存储中。

托肯认证

此身份验证方案使用简单的基于令牌的HTTP身份验证方案。令牌身份验证适用于客户端服务器设置,例如本机桌面和移动客户端.

使用托肯认证你需要的计划配置身份验证类包括托肯认证,另外还包括rest_framework.authtoken在你的INSTALLED_APPS背景:

INSTALLED_APPS = [
    ...
    'rest_framework.authtoken'
]

注:确保跑manage.py migrate在改变你的设置之后。这个rest_framework.authtokenAPP提供Django数据库迁移。


您还需要为用户创建令牌。

from rest_framework.authtoken.models import Token

token = Token.objects.create(user=...)
print(token.key)

对于要进行身份验证的客户端,应该将令牌密钥包括在Authorizationhttp标头。键应该以字符串文字“Token”作为前缀,用空格分隔这两个字符串。例如:

Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b

注:如果要在标题中使用不同的关键字,如Bearer,简单子类托肯认证并设置keyword类变量。

如果鉴定成功,托肯认证提供下列凭据。

  • request.user将是一个DjangoUser举个例子。
  • request.auth将是rest_framework.authtoken.models.Token举个例子。

被拒绝权限的未经身份验证的响应将导致HTTP 401 Unauthorized使用适当的WWW-身份验证头进行响应。例如:

WWW-Authenticate: Token

这个curl命令行工具对于测试令牌认证API可能很有用。例如:

curl -X GET http://127.0.0.1:8000/api/example/ -H 'Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b'

注:如果你用托肯认证在生产中,必须确保api只在https.


生成令牌
用信号

如果希望每个用户都有一个自动生成的令牌,则只需捕获用户的令牌即可post_save信号。

from django.conf import settings
from django.db.models.signals import post_save
from django.dispatch import receiver
from rest_framework.authtoken.models import Token

@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
    if created:
        Token.objects.create(user=instance)

请注意,您希望确保将此代码段放置在已安装的models.py模块,或由Django在启动时导入的其他位置。

如果已经创建了一些用户,则可以为所有现有用户生成令牌,如下所示:

from django.contrib.auth.models import User
from rest_framework.authtoken.models import Token

for user in User.objects.all():
    Token.objects.get_or_create(user=user)
通过公开API端点

使用时托肯认证,您可能希望为客户端提供一种机制,以便获得给定用户名和密码的令牌。REST框架提供了一个内置视图来提供这种行为。若要使用它,请添加obtain_auth_token查看您的URLCONF:

from rest_framework.authtoken import views
urlpatterns += [
    url(r'^api-token-auth/', views.obtain_auth_token)
]

请注意,模式的URL部分可以是您想要使用的任何部分。

这个obtain_auth_token视图将在有效时返回JSON响应usernamepassword字段使用表单数据或JSON发布到视图:

{ 'token' : '9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b' }

注意,默认的obtain_auth_token视图显式地使用JSON请求和响应,而不是在设置中使用默认呈现程序和解析器类。

默认情况下,不对obtain_auth_token视野。如果您确实希望应用节流,则需要重写视图类,并使用throttle_classes属性。

如果需要自定义版本的obtain_auth_token视图,则可以通过子类对ObtainAuthToken查看类,并在url conf中使用它。

例如,您可能会返回token价值:

from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.authtoken.models import Token
from rest_framework.response import Response

class CustomAuthToken(ObtainAuthToken):

    def post(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data,
                                           context={'request': request})
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data['user']
        token, created = Token.objects.get_or_create(user=user)
        return Response({
            'token': token.key,
            'user_id': user.pk,
            'email': user.email
        })

在你的urls.py:

urlpatterns += [
    url(r'^api-token-auth/', CustomAuthToken.as_view())
]
与Django管理

还可以通过管理界面手动创建令牌。如果您正在使用大型用户群,我们建议您对TokenAdmin类来自定义它以满足您的需要,更具体地说,通过声明user字段ASraw_field.

your_app/admin.py:

from rest_framework.authtoken.admin import TokenAdmin

TokenAdmin.raw_id_fields = ['user']
使用Django management e.py命令

由于版本3.6.4,可以使用以下命令生成用户令牌:

./manage.py drf_create_token <username>

此命令将返回给定用户的API令牌,如果它不存在,则创建它:

Generated token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b for user user1

如果要重新生成令牌(例如,如果令牌已被破坏或泄漏),则可以传递一个附加参数:

./manage.py drf_create_token -r <username>

专用认证

此身份验证方案使用Django的默认会话后端进行身份验证。会话身份验证适用于运行在与您的网站相同的会话上下文中的Ajax客户端。

如果鉴定成功,专用认证提供下列凭据。

  • request.user将是一个DjangoUser举个例子。
  • request.auth将是None.

被拒绝权限的未经身份验证的响应将导致HTTP 403 Forbidden回应。

如果使用AJAX风格的API和SessionAuthentication,则需要确保为任何“不安全”的HTTP方法调用包括一个有效的CSRF令牌,如PUT, PATCH, POSTDELETE请求。见Django CSRF文件更多细节。

警告:在创建登录页面时始终使用Django的标准登录视图。这将确保您的登录视图受到适当保护。

REST框架中的CSRF验证与标准Django略有不同,因为需要支持对相同视图的会话和非基于会话的身份验证。这意味着只有经过身份验证的请求才需要CSRF令牌,匿名请求可以在没有CSRF令牌的情况下发送。此行为不适用于登录视图,应该始终应用CSRF验证。

远程用户认证

此身份验证方案允许您将身份验证委托给web服务器,这将设置REMOTE_USER环境变量

要使用它,你必须django.contrib.auth.backends.RemoteUserBackend(或子类)AUTHENTICATION_BACKENDS背景。默认情况下,RemoteUserBackend创造User对象用于不存在的用户名。若要更改此行为和其他行为,请参阅Django文档.

如果鉴定成功,远程用户认证提供下列凭据:

  • request.user将是一个DjangoUser举个例子。
  • request.auth将是None.

有关配置身份验证方法的信息,请参阅Web服务器的文档,例如:

自定义认证

若要实现自定义身份验证方案,请将BaseAuthentication并覆盖.authenticate(self, request)方法。方法应该返回两个元组。(user, auth)如果身份验证成功,或None不然的话。

在某些情况下而不是返回None,您可能想提出一个AuthenticationFailed异常.authenticate()方法。

通常,您应该采取的方法是:

  • 如果未尝试身份验证,则返回None...还在使用的任何其他身份验证方案仍将被检查。
  • 如果尝试验证但失败,则引发AuthenticationFailed例外。将立即返回错误响应,而不检查任何其他身份验证方案,而不检查任何权限检查。

你,你们可以,可能还覆盖.authenticate_header(self, request)方法。如果实现,它应该返回一个字符串,该字符串将用作WWW-Authenticate头中的HTTP 401 Unauthorized回应。

如果.authenticate_header()方法,则身份验证方案将返回。HTTP 403 Forbidden当未经身份验证的请求被拒绝访问时,响应。


注:当自定义身份验证器被请求对象的.user.auth属性,您可能会看到AttributeError重拾为.WrappedAttributeError...这对于防止外部属性访问抑制原始异常是必要的。Python不会意识到AttributeError起源于您的自定义身份验证器,并将相反地假设请求对象没有.user.auth财产。这些错误应由您的身份验证程序修复或以其他方式处理。


下面的示例将在名为“X-username”的自定义请求头中验证用户名给出的任何传入请求。

from django.contrib.auth.models import User
from rest_framework import authentication
from rest_framework import exceptions

class ExampleAuthentication(authentication.BaseAuthentication):
    def authenticate(self, request):
        username = request.META.get('HTTP_X_USERNAME')
        if not username:
            return None

        try:
            user = User.objects.get(username=username)
        except User.DoesNotExist:
            raise exceptions.AuthenticationFailed('No such user')

        return (user, None)

第三方包

下面的第三方包也是可用的。

Django OAuth工具包

这个Django OAuth工具包包提供了OAuth2.0支持,并与Python3.4+一起工作。此包由以下人员维护:埃文并使用优秀的OAuthLib...这个包有很好的文档和支持,目前是我们的推荐的OAuth 2.0支持包.

安装与配置

安装使用pip.

pip install django-oauth-toolkit

将该包添加到您的INSTALLED_APPS并修改REST框架设置。

INSTALLED_APPS = [
    ...
    'oauth2_provider',
]

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
    ]
}

有关详细信息,请参阅Django REST框架-开始文件。

Django REST框架

这个Django REST框架软件包提供了对REST框架的OAuth1和OAuth2支持。

这个包以前直接包含在REST框架中,但现在作为第三方包得到了支持和维护。

安装与配置

使用pip.

pip install djangorestframework-oauth

有关配置和使用的详细信息,请参阅Django REST框架OAuth文档认证权限.

JSON Web令牌认证

JSONWeb令牌是一个非常新的标准,可以用于基于令牌的身份验证。与内置TokenAuthentication方案不同,JWT身份验证不需要使用数据库来验证令牌。用于JWT身份验证的包是djangorest框架-simplejwt它提供了一些特性以及一个可插拔的令牌黑名单应用程序。

Hawk HTTP认证

这个霍克雷库构建在莫霍克库可以让您使用霍克在API中签名请求和响应。霍克允许双方使用共享密钥签名的消息安全地相互通信。它是基于HTTP MAC访问认证(基于OAuth 1.0).

http签名认证

http签名(当前为IETF草案)为HTTP消息提供一种实现原始身份验证和消息完整性的方法。类似于Amazon的HTTP签名方案,它的许多服务使用,它允许无状态,每次请求的身份验证。埃尔维奥·托卡里诺维护djangorestframework-http签名(过时)包,它提供了一种易于使用的HTTP签名身份验证机制。的更新分叉版本。djangorestframework-http签名,也就是DRF-httpsig.

乔瑟

乔瑟库提供了一组视图来处理基本操作,如注册、登录、注销、密码重置和帐户激活。该包使用自定义用户模型,并使用基于令牌的身份验证。这是一个准备使用Django身份验证系统的REST实现。

Django-休息-AUTH

Django-休息-AUTH库提供了一组RESTAPI端点,用于注册、身份验证(包括社交媒体身份验证)、密码重置、检索和更新用户详细信息等。通过拥有这些API端点,您的客户端应用程序(如AngularJS、IOS、Android等)可以通过REST API独立地与Django后端站点进行用户管理。

Django-REST-框架-社会-OAuth2

Django-REST-框架-社会-OAuth2库提供了一种简单的方法来集成社交插件(Facebook、Twitter、Google等)。到您的身份验证系统和一个简单的OAuth2设置。有了这个库,您将能够基于外部令牌(例如Facebook访问令牌)对用户进行身份验证,将这些令牌转换为“内部”OAuth2令牌,并使用和生成OAuth2令牌来验证您的用户。

Django-REST-Knox

Django-REST-Knox库提供模型和视图,以便以比内置TokenAuthentication方案更安全和可扩展的方式处理基于令牌的身份验证,同时考虑到单页应用程序和移动客户端。它提供每个客户端令牌,并在提供其他身份验证(通常是基本身份验证)时生成它们,删除令牌(提供服务器强制注销)和删除所有令牌(注销用户登录的所有客户端)。

无字

无字添加(媒体,正方形现金启发)无密码支持Django REST框架自己的托肯认证方案。用户登录并使用发送给联系人的令牌注册,比如电子邮件地址或移动电话号码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Django-rest-framework是一个用于构建Web API的强大框架,它提供了许多有用的工具和库,可以帮助我们轻松地构建出一个安全可靠的用户注册和登录系统。 下面是一个简单的Django-rest-framework用户注册与登录的实现: 首先,我们需要安装Django-rest-framework: ``` pip install djangorestframework ``` 接着,我们需要在settings.py文件中添加以下配置: ```python INSTALLED_APPS = [ # ... 'rest_framework', ] REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.TokenAuthentication', ], 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', ], } ``` 上面的配置将启用TokenAuthentication身份验证和IsAuthenticated权限,这将确保只有已登录的用户才能访问我们的API。 现在,我们可以创建一个名为"users"的Django应用程序,并定义以下模型: ```python from django.db import models from django.contrib.auth.models import AbstractUser class User(AbstractUser): pass ``` 接着,我们需要定义序列化器来将User模型转换为JSON格式: ```python from rest_framework import serializers from .models import User class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ('username', 'email', 'password') extra_kwargs = {'password': {'write_only': True}} def create(self, validated_data): user = User.objects.create_user( username=validated_data['username'], email=validated_data['email'], password=validated_data['password'] ) return user ``` 上面的代码定义了一个UserSerializer序列化器,将User模型转换为JSON格式。我们使用Meta类来指定模型和要序列化的字段,以及一些额外的参数。在create方法中,我们使用create_user方法创建新用户。 现在,我们可以定义视图来处理用户注册和登录请求: ```python from rest_framework import generics, permissions, status from rest_framework.response import Response from rest_framework.authtoken.models import Token from rest_framework.views import APIView from django.contrib.auth import authenticate, login from .models import User from .serializers import UserSerializer class RegisterView(generics.CreateAPIView): queryset = User.objects.all() serializer_class = UserSerializer permission_classes = [permissions.AllowAny] def post(self, request): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) class LoginView(APIView): permission_classes = [permissions.AllowAny] def post(self, request): username = request.data.get('username') password = request.data.get('password') user = authenticate(request, username=username, password=password) if user is not None: login(request, user) token, created = Token.objects.get_or_create(user=user) return Response({'token': token.key}) else: return Response({'error': 'Invalid credentials'}) ``` 上面的代码定义了RegisterView和LoginView视图。RegisterView视图处理用户注册请求,LoginView视图处理用户登录请求。我们在视图中使用UserSerializer序列化器来验证输入数据,并使用TokenAuthentication身份验证来保护API。 现在我们已经完成了用户注册和登录的实现。可以使用POST请求来测试我们的API: - 用户注册: ``` POST /api/register/ { "username": "testuser", "email": "[email protected]", "password": "testpassword" } ``` - 用户登录: ``` POST /api/login/ { "username": "testuser", "password": "testpassword" } ``` 如果登录成功,API将返回一个包含Token身份验证密钥的JSON响应。现在,我们可以将此密钥用于所有受保护的API请求中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

QMQ2021

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值