Django - 使用电子邮件登录

130

我希望Django通过电子邮件进行用户身份验证,而不是通过用户名。一种方法是将电子邮件值提供为用户名值,但我不想这样做。原因是,我有一个URL/profile/<username>/,因此我不能有一个URL /profile/abcd@gmail.com/

另一个原因是所有电子邮件都是唯一的,但有时会出现用户名已被使用的情况。因此,我正在自动创建用户名为fullName_ID

我该如何让Django只使用电子邮件进行身份验证?

这是我创建用户的方式。

username = `abcd28`
user_email = `abcd@gmail.com`
user = User.objects.create_user(username, user_email, user_pass)

这是我登录的方式。

email = request.POST['email']
password = request.POST['password']
username = User.objects.get(email=email.lower()).username
user = authenticate(username=username, password=password)
login(request, user)

除了先获取用户名之外,还有其他登录方式吗?

18个回答

2
你需要自定义ModelBackend类。 我的简单代码:
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth import get_user_model

class YourBackend(ModelBackend):

  def authenticate(self, username=None, password=None, **kwargs):
    UserModel = get_user_model()
    if username is None:
        username = kwargs.get(UserModel.USERNAME_FIELD)
    try:
        if '@' in username:
            UserModel.USERNAME_FIELD = 'email'
        else:
            UserModel.USERNAME_FIELD = 'username'

        user = UserModel._default_manager.get_by_natural_key(username)
    except UserModel.DoesNotExist:
        UserModel().set_password(password)
    else:
        if user.check_password(password) and self.user_can_authenticate(user):
            return user

settings.py文件中,添加:

AUTHENTICATION_BACKENDS = ['path.to.class.YourBackend']

1
请更新您的代码,将request参数包含在Django 2.1.1的authenticate方法中。 - Ganesh

1
from django.contrib.auth.models import User

from django.db import Q

class EmailAuthenticate(object):

    def authenticate(self, username=None, password=None, **kwargs):
        try:
            user = User.objects.get(Q(email=username) | Q(username=username))
        except User.DoesNotExist:
            return None
        except MultipleObjectsReturned:
            return User.objects.filter(email=username).order_by('id').first()

        if user.check_password(password):
            return user
        return None

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

然后在 settings.py 中:
AUTHENTICATION_BACKENDS = (
  'articles.backends.EmailAuthenticate',
)

这里的 articles 是我的 Django 应用程序,backends.py 是应用程序内部的 Python 文件,EmailAuthenticate 是我在 backends.py 文件中定义的身份验证后端类。


0

针对Django 2

username = get_object_or_404(User, email=data["email"]).username
        user = authenticate(
            request, 
            username = username, 
            password = data["password"]
        )
        login(request, user)

0
如果您创建了自定义数据库,并且想要验证您的电子邮件和密码,请按以下步骤操作:
  1. 使用 models.objects.value_list('db_columnname').filter(db_emailname=textbox email) 获取电子邮件和密码

2.将获取到的值赋给列表 object_query_list

3.将列表转换为字符串

例如:

  1. Views.py 中获取 Html 的 Email_idPassword

    u_email = request.POST.get('uemail')

    u_pass = request.POST.get('upass')

  2. 从数据库中获取 Email id 和密码

    Email = B_Reg.objects.values_list('B_Email',flat=True).filter(B_Email=u_email)

    Password = B_Reg.objects.values_list('Password',flat=True).filter(B_Email=u_email)

  3. Query 值集合中获取 Email id 和密码值的列表

    Email_Value = Email[0]

    Password_Value=Password[0]

  4. 将列表转换为字符串

    string_email = ''.join(map(str, Email_Value))

    string_password = ''.join(map(str, Password_Value))

最后,您的登录条件

if (string_email==u_email and string_password ==u_pass)

0

使用电子邮件进行 Django 2.x 身份验证

def admin_login(request):
if request.method == "POST":
    email = request.POST.get('email', None)
    password = request.POST.get('password', None)
    try:
        get_user_name = CustomUser.objects.get(email=email)
        user_logged_in =authenticate(username=get_user_name,password=password)
        if user_logged_in is not None:
            login(request, user_logged_in)
            messages.success(request, f"WelcomeBack{user_logged_in.username}")
            return HttpResponseRedirect(reverse('backend'))
        else:
            messages.error(request, 'Invalid Credentials')
            return HttpResponseRedirect(reverse('admin_login'))
    except:
        messages.warning(request, 'Wrong Email')
        return HttpResponseRedirect(reverse('admin_login'))

else:
    if request.user.is_authenticated:
        return HttpResponseRedirect(reverse('backend'))
    return render(request, 'login_panel/login.html')

0

所有这些都对于本应该是简单问题而言过于复杂了。

检查是否存在使用该电子邮件的用户,然后获取该用户的用户名作为 Django 的 authenticate() 方法的参数。

try:
    user = User.objects.get(email = request_dict['email'])
    user = authenticate(username = user.username, password = request_dict['password'])
except:
    return HttpResponse('User not found.', status = 400)

-1

默认用户模型继承/扩展了一个抽象类。框架应该对一定程度的更改或修改宽容。

一个更简单的方法是执行以下操作: 这是在虚拟环境中进行的

  1. 转到您的Django安装位置并找到Lib文件夹
  2. 导航到django/contrib/auth/
  3. 找到并打开models.py文件。找到AbstractUser类第315行

在电子邮件属性的第336行上添加唯一并将其设置为true

email = models.EmailField(_('email address'), blank=True,unique=True)

USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']

完成,执行 makemigrations 和 migrate。
请自行承担风险。

-1

非常简单。不需要任何额外的类。

当您使用电子邮件创建和更新用户时,只需将用户名字段设置为电子邮件即可。

这样,当您进行身份验证时,用户名字段将是电子邮件的相同值。

代码:

# Create
User.objects.create_user(username=post_data['email'] etc...)

# Update
user.username = post_data['email']
user.save()

# When you authenticate
user = authenticate(username=post_data['email'], password=password)

2
请添加一些示例代码以帮助演示您的答案如何解决问题。 - Marcello B.
2
如果您不添加其他信息,@CasmanRidder的答案将被删除。 - 10 Rep

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接