gpt4 book ai didi

Django 休息框架 JWT 和自定义身份验证后端

转载 作者:行者123 更新时间:2023-12-03 17:16:41 25 4
gpt4 key购买 nike

我有一个自定义用户模型并创建了一个自定义身份验证后端。我正在使用 django rest framework , 和 django rest framework JWT用于 token 认证。

用户模型:

class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(
unique=True,
max_length=254,
)
first_name = models.CharField(max_length=15)
last_name = models.CharField(max_length=15)
mobile = models.IntegerField(unique=True)
date_joined = models.DateTimeField(default=timezone.now)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
objects = UserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'last_name', 'mobile']

验证后端:
class EmailOrMobileAuthBackend(object):
def authenticate(self, username=None, password=None):
try:
user = get_user_model().objects.get(email=username)
if user.check_password(password):
return user
except User.DoesNotExist:
if username.isdigit():
try:
user = get_user_model().objects.get(mobile=username)
if user.check_password(password):
return user
except User.DoesNotExist:
return None
else:
return None

def get_user(self, user_id):
try:
return get_user_model().objects.get(pk=user_id)
except User.DoesNotExist:
return None

并在settings.py中添加:
AUTHENTICATION_BACKENDS = ('accounts.email_mobile_auth_backend.EmailOrMobileAuthBackend',)

在登录 django 管理站点时,电子邮件和手机号码都可以很好地验证用户身份。但是,当我尝试使用 django rest framework JWT 为用户获取 token 时,我收到一个错误:
curl -X POST -d "email=admin@gmail.com&password=123123" http://localhost/api-token-auth/

"non_field_errors": [
"Unable to log in with provided credentials."
]

我还在 Rest 框架的默认身份验证中添加了自定义身份验证后端类,但它仍然无法正常工作:
REST_FRAMEWORK = {
...
'DEFAULT_AUTHENTICATION_CLASSES': (
'accounts.email_mobile_auth_backend.EmailOrMobileAuthBackend',
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
),
}

我错过了什么?为什么在登录 django 管理站点时它可以工作,但在使用 django rest framework jwt 获取 token 时出错?

更新

我按照建议制作了另一个身份验证后端并将其添加到 DEFAULT_AUTHENTICATION_CLASSES ,但即使这样也行不通。
class DrfAuthBackend(BaseAuthentication):
def authenticate(self, username=None, password=None):
try:
user = get_user_model().objects.get(email=username)
if user.check_password(password):
return user, None
except User.DoesNotExist:
if username.isdigit():
try:
user = get_user_model().objects.get(mobile=username)
if user.check_password(password):
return user, None
except User.DoesNotExist:
return None
else:
return None

设置:
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAdminUser',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'accounts.email_mobile_auth_backend.EmailOrMobileAuthBackend',
'accounts.email_mobile_auth_backend.DrfAuthBackend',
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
),
}

更新

更改 args在来自 username 的身份验证类中至 email似乎可以用于获取 auth_token但同样无法登录管理站点。
class EmailOrMobileAuthBackend(object):
def authenticate(self, email=None, password=None):
try:
user = get_user_model().objects.get(email=email)
if user.check_password(password):
return user
except User.DoesNotExist:
if email.isdigit():
try:
user = get_user_model().objects.get(mobile=email)
if user.check_password(password):
return user
except User.DoesNotExist:
return None
else:
return None

def get_user(self, user_id):
try:
return get_user_model().objects.get(pk=user_id)
except User.DoesNotExist:
return None

最佳答案

您应该查看 DRF documentation用于自定义身份验证后端。

我认为您的自定义身份验证后端正在破坏它,您可以通过从 DRF 设置中删除您的来解决它:

REST_FRAMEWORK = {
...
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
),
}

或者通过修复您的与 Django 自定义身份验证基本不同的方法,因为您应该从 authentication.BaseAuthentication 扩展它返回一个元组。
from rest_framework import authentication


class DrfAuthBackend(authentication.BaseAuthentication):
def authenticate(self, email=None, password=None):
try:
user = get_user_model().objects.get(email=email)
if user.check_password(password):
return user, None
except User.DoesNotExist:
if email.isdigit():
try:
user = get_user_model().objects.get(mobile=email)
if user.check_password(password):
return user, None
except User.DoesNotExist:
return None
else:
return None

然后在 DRF 设置中使用它:
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAdminUser',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'accounts.email_mobile_auth_backend.DrfAuthBackend',
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
),
}

对于 Django 登录:
class EmailOrMobileAuthBackend(object):
def authenticate(self, username=None, password=None):
try:
user = get_user_model().objects.get(email=username)
if user.check_password(password):
return user
except User.DoesNotExist:
if username.isdigit():
try:
user = get_user_model().objects.get(mobile=username)
if user.check_password(password):
return user
except User.DoesNotExist:
return None
else:
return None

def get_user(self, user_id):
try:
return get_user_model().objects.get(pk=user_id)
except User.DoesNotExist:
return None

然后是设置:
AUTHENTICATION_BACKENDS = ('accounts.email_mobile_auth_backend.EmailOrMobileAuthBackend',)

关于Django 休息框架 JWT 和自定义身份验证后端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44209730/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com