【问题标题】:Django authenticate function that accepts extra fields接受额外字段的 Django 身份验证函数
【发布时间】:2018-04-12 12:25:18
【问题描述】:

那个django验证函数接受两个参数,例如

user = authenticate(username=username, password=password)

,但我想传入一个附加参数来验证条目。是否可以这样做,或者是否可以覆盖身份验证功能来实现这一目标?

请指教,谢谢。

【问题讨论】:

    标签: python django django-rest-framework


    【解决方案1】:

    authenticate 只是一个 python 函数,您可以使用 *args & **kwargs 传递多个参数,并且您可以覆盖像 (How to override authenticate method ) 这样的身份验证方法来在那里添加您自己的验证。

    【讨论】:

      【解决方案2】:

      据我所知,authenticate() 函数将任何关键字参数作为凭据。它只是将凭据转发到配置的身份验证后端。因此,这实际上取决于您对传递的参数所做的身份验证后端。

      这意味着您可以将任何您想要的内容传递给authenticate() 函数,但您可能需要实现自己的身份验证后端。您可以通过在 settings.py 中指定自定义身份验证后端来实现:

      AUTHENTICATION_BACKENDS = (
          'django.contrib.auth.backends.ModelBackend',
          'confirm.django.auth.backends.EmailBackend',
      )
      

      这是EmailBackend的代码:

      from django.contrib.auth.backends import ModelBackend, UserModel
      
      
      class EmailBackend(ModelBackend):  # pylint: disable=too-few-public-methods
          '''
          Authentication backend class which authenticates the user against his
          e-mail address instead of his username.
          '''
      
          def authenticate(self, username=None, password=None, **kwargs):  # pylint: disable=unused-argument
              '''
              Authenticate the user via his e-mail address.
      
              :param str username: The username used to authenticate
              :param str password: The password used to authenticate
              :return: When successful, the User model is returned
              :rtype: User model or None
              '''
              try:
                  user = UserModel.objects.get(email=username)
              except UserModel.DoesNotExist:
                  return None
              else:
                  if user.check_password(password) and self.user_can_authenticate(user):
                      return user
      
              return None
      

      当用户使用电子邮件地址登录时,凭据将传递给ModelBackend.authenticate() 方法,该方法将失败,因为没有与电子邮件地址匹配的用户名。之后,调用EmailBackend.authenticate() 方法,该方法将成功(如果密码匹配)。返回User 实例的第一个后端“获胜”。

      所以这取决于你想做什么。

      如果您只想允许用户使用他们的用户名或电子邮件地址(或任何其他字段)登录,那么这就是要走的路。只需创建一个新的身份验证后端并将其与django.contrib.auth.backends.ModelBackend 一起添加到AUTHENTICATION_BACKENDS

      如果您需要为登录验证额外的字段,比如customer IDusernamepassword 这样的三元组,您还需要创建自己的后端。但是,这一次后端应该是AUTHENTICATION_BACKENDS中唯一配置的一个,因此将django.contrib.auth.backends.ModelBackend替换为它。

      如果您想了解有关自定义身份验证的更多信息,请前往brilliant docs

      【讨论】:

        猜你喜欢
        • 2023-03-20
        • 2019-03-17
        • 2019-11-29
        • 2018-12-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-22
        • 2017-03-19
        相关资源
        最近更新 更多