django authenticate--用户身份认证

authenticate
Django的contrib.auth模块中的authenticate()函数用于对用户的凭据进行身份验证,与已配置的身份验证后端进行比较。

当用户尝试登录时,authenticate()函数将使用用户的凭据(即用户名和密码)作为参数进行调用,该函数然后检查可用的身份验证后端以验证凭据,这些后端在项目的settings.py文件中定义,如果凭据有效,则authenticate()函数返回已认证的用户对象;否则,它返回None。
在成功身份验证后,可以使用Django的login()函数登录用户。

认证后端
1.AUTHENTICATION_BACKENDS是Django设置中的一个参数,它定义了用于身份验证的后端认证方式。这个参数是一个字符串列表,包含Django认证系统使用的认证后端类的全名。

2.当用户尝试进行身份验证时,Django将按照AUTHENTICATION_BACKENDS中定义的顺序,尝试每个后端认证方式,直到找到一个认证方式成功为止。如果所有后端认证方式都失败,则身份验证失败。

3.默认情况下,Django使用ModelBackend作为身份验证后端,它基于Django中的用户模型进行身份验证。除此之外,Django还提供了其他的身份验证后端,如LDAPBackend、RemoteUserBackend等,也可以自定义身份验证后端。

4.通过配置AUTHENTICATION_BACKENDS参数,可以对身份验证后端进行定制,以满足具体项目的需求。例如,如果你的项目需要使用LDAP进行用户身份验证,则可以添加LDAPBackend到AUTHENTICATION_BACKENDS列表中,以便Django使用LDAPBackend进行身份验证。

from django.contrib.auth import authenticate
from django.contrib.auth import login as user_login
def my_login(request):
    """
    登录视图
    :param request:
    :return:
    """
    if request.method == "POST":
        login_form = users_form.UserForm(request.POST)
        if login_form.is_valid():
            username = login_form.cleaned_data['username']
            password = login_form.cleaned_data['password']
            myuser = authenticate(username=username, password=password)
            if myuser is not None:
                user_login(request, myuser)

这段代码使用Django的contrib.auth模块来进行用户身份验证和登录。
首先,它调用authenticate()函数验证用户的凭据,如果凭据有效,则authenticate()函数将返回已认证的用户对象,并将其赋给myuser变量。如果凭据无效,则authenticate()函数将返回None。
接着,代码检查myuser变量是否为None。如果myuser不为None,则说明凭据有效,并且代码将调用user_login()函数来将该用户登录到当前会话中。user_login()函数需要传递一个request对象和已认证的用户对象。登录成功后,用户可以访问需要认证的页面和视图。
如果myuser为None,则说明凭据无效,用户无法登录。

myuser 和 request.user 是两个不同的对象,其区别在于:
1.myuser 表示通过用户名和密码认证成功后得到的用户对象, 是通过表单验证之后从数据库中查询出来的用户对象,即 authenticate 方法返回的对象。主要用来检查用户输入的用户名和密码是否正确,并在认证成功后设置一些 session 变量。
2.request.user 表示当前请求的用户对象,是通过 Django 的认证系统得到的用户对象,包括通过认证的用户和未认证的用户。如果用户已通过认证,则该对象是一个 User 实例,否则是一个 AnonymousUser 实例。 主要用来获取当前认证的用户信息,例如用户的用户名、邮箱等。这些信息通常用来显示在页面上,或者用来判断当前用户是否有权限进行某些操作。

因此,在这个方法中,myuser 和 request.user 作用是相同的,都是用来判断用户是否已通过认证,但是可能是不同的对象,因为 myuser 只在用户认证成功后才会有值,而 request.user 则是在每个请求中都会有值,不论用户是否通过认证。同时,在这个方法中,myuser 和 request.user 都可以用来检查用户是否已通过认证,但是只有 request.user 才可以用来获取当前认证的用户信息。

authenticate函数如下:


@sensitive_variables("credentials")
def authenticate(request=None, **credentials):
    """
    If the given credentials are valid, return a User object.
    """
    for backend, backend_path in _get_backends(return_tuples=True):
        backend_signature = inspect.signature(backend.authenticate)
        try:
            backend_signature.bind(request, **credentials)
        except TypeError:
            # This backend doesn't accept these credentials as arguments. Try
            # the next one.
            continue
        try:
            user = backend.authenticate(request, **credentials)
        except PermissionDenied:
            # This backend says to stop in our tracks - this user should not be
            # allowed in at all.
            break
        if user is None:
            continue
        # Annotate the user object with the path of the backend.
        user.backend = backend_path
        return user

_get_backends会从settings.py中读取AUTHENTICATION_BACKENDS定义的后端路径:

def _get_backends(return_tuples=False):
    backends = []
    for backend_path in settings.AUTHENTICATION_BACKENDS:
        backend = load_backend(backend_path)
        backends.append((backend, backend_path) if return_tuples else backend)
    if not backends:
        raise ImproperlyConfigured(
            "No authentication backends have been defined. Does "
            "AUTHENTICATION_BACKENDS contain anything?"
        )
    return backends
AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.ModelBackend',
    'backends.user_backend.UserBackend'
]

AUTHENTICATION_BACKENDS列表中包含了两个认证后端,分别是ModelBackend和UserBackend。Django将按照列表中的顺序依次尝试这两个认证后端,直到找到一个成功为止。

UserBackend需要继承BaseBackend并实现一个authenticate函数:

from django.contrib.auth.backends import BaseBackend
from users.models import MyUser


class UserBackend(BaseBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        try:
            myuser = MyUser.objects.get(name=username)
            if myuser.check_password(password):
                return myuser
        except MyUser.DoesNotExist as e:
            print("user no exist", e)
            return None

    def get_user(self, user_id):
        try:
            return MyUser.objects.get(pk=user_id)
        except MyUser.DoesNotExist:
            return None
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 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
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值