当前位置: 首页 > 知识库问答 >
问题:

Python Django电子邮件登录/验证用户是无与ModelBackend, CustomUserModel

章誉
2023-03-14

我试图在视图中进行电子邮件登录/验证。py,但它返回“user is None”。我尝试只使用电子邮件登录,而不是用户名。如果我尝试使用电子邮件登录,则在视图中可能会出现“用户无”的自定义错误消息“无效凭据”。皮耶。

Django版本:3.0。4//模型:自定义用户模型(AbstractBaseUser)-

问题1:在Views.py返回用户为无//问题2:模型有一个密码(默认),密码1和密码2(都由UserCreationForm定义)

  1. 用户和模型。派克
from django.conf import settings
from django.contrib.auth import authenticate
from django.contrib.auth.models import AbstractBaseUser
from django.db import models
from django import forms
from django.utils import timezone

from .users_managers import UserManager

class User(AbstractBaseUser):
    USERNAME_FIELD = 'email'

    email = models.EmailField(
        verbose_name='email',
        max_length=255,
        db_index=True,
        unique=True,
    )
    password1 = PasswordModelField('password', max_length=50, error_messages={something},)
    password2 = PasswordModelField('password check', max_length=50, error_messages={something},)
    ...
    objects = UserManager()

    class Meta:
        db_table = 'users'
        verbose_name = 'user'
        verbose_name_plural = 'users'

from django import forms
from django.contrib.auth import authenticate, get_user_model
from django.contrib.auth.forms import ReadOnlyPasswordHashField

from .users_models import User

class UserCreationForm(forms.ModelForm):
    password1 = forms.CharField(
        label='password',
        strip=False,
        widget=forms.PasswordInput(attrs={'placeholder': 'something'}),
        error_messages={something},
    )
    password2 = forms.CharField(
        label='password check',
        widget=forms.PasswordInput,
        error_messages={something},
    )

   class Meta:
        model = User
        fields = ('email', 'password1', 'password2', ... )
   ...
   def save(self, commit=True):
        user = super().save(commit=False)
        user.set_password(self.cleaned_data['password1']) # set_password

        if commit:
            user.save()
        return user

class UserLoginForm(forms.Form):
    email = forms.EmailField(
        label='email',
        max_length=255,
        widget=forms.TextInput(attrs={'autofocus': True}),
    )
    password = forms.CharField(
        label='password',
        strip=False,
        widget=forms.PasswordInput,
    )
from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend
# from django.contrib.auth.models import check_password
from django.contrib.auth.hashers import check_password

class EmailBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None):
        user_model = get_user_model()
        if '@' in username:
            kwargs = {'email': username}
        else:
            kwargs = {'username': username}
        try:
            user = user_model.objects.get(**kwargs)
            if user.check_password(password):
                return user
            else:
                return None
        except user_model.DoesNotExist:
            return None

    def get_user(self, id=None):
        user_model = get_user_model()
        try:
            return user_model.objects.get(pk=id)
        except user_model.DoesNotExist:
            return None
# AUTH_USER_MODEL = 'apps.User' # if I use this code, It returns errors. 

AUTHENTICATION_BACKENDS = [
    'apps.backend.EmailBackend',
    'django.contrib.auth.backends.ModelBackend',
]
{% extends 'apps/base.html' %}
{% load static %}
{% block content %}
<div class="container">
    <h1>login</h1>
    {% if error %}
        <p>{{ error }}</p>
    {% endif %}
    <form method="POST" action="{% url 'login' %}">
        {% csrf_token %}
        {{ form.as_p }}
        <input type="submit" class="btn btn-primary" value="login">
    </form>
</div>
{% endblock %}
from django import forms
from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.template import loader
from django.contrib import auth, admin
from django.contrib.auth import login, authenticate
from django.contrib.auth.models import User, Group
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.contrib.redirects.models import Redirect
from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponseRedirect
from django.apps import AppConfig

from apps.users_forms import UserCreationForm, UserLoginForm, UserChangeForm
from apps.users_models import User

@csrf_exempt
def signup(request):
    if request.method == 'POST':
        creation_form = UserCreationForm(request.POST)
        if creation_form.is_valid():
            creation_form.save()
            return redirect('index')
    else:
        creation_form = UserCreationForm()
    return render(request, 'signup.html', {'form': creation_form})


@csrf_exempt
def signin(request):
    if request.user.is_authenticated:
        return redirect(reverse('index'))
    if request.method == "POST":
        login_form = UserLoginForm(request.POST)

        if login_form.is_valid():
            username = login_form.cleaned_data['email'] # take email in form for username
            password = login_form.cleaned_data['password']
            user = authenticate(username=username, password=password)
            if user is not None: # not going here !!!
                if user.is_active:
                    login(request, user)
                    return redirect('index')
            else:
                return render(request, 'login.html', 
                    {'form': login_form, 'error': 'invalid credentials'}) 
                # errors here !!!!! always views.py returns this messages !!!!!
    else:
        login_form = UserLoginForm()
        return render(request, 'login.html', {'form': login_form})

我怎样才能解决这个问题?

共有1个答案

董高畅
2023-03-14

试试这个

user = authenticate(email=email, password=password)

或者用check_password

from django.contrib.auth.hashers import check_password


# inside view function
# ...
user = User.objects.get(email=email)
if check_password(password, user.password):
    if user.is_active:
        login(request, user)
# ...
 类似资料:
  • 我正在提示我的应用程序用户提供电子邮件凭据。 在用户插入电子邮件并通过后,我想验证该帐户。 我正在使用javax。邮政有没有办法验证帐户?只确保凭据确实有效——否则我想显示一个无效用户并传递消息。 也许是某种表演方式: 并在不发送任何内容的情况下检查身份验证异常。

  • null 我需要重新验证用户,最好的方法是什么?在用户登录后,如何切换的状态? 谢谢

  • 我对Firebase及其电子邮件验证流程有疑问。我可以创建一个新用户,电子邮件与一个链接,以验证电子邮件地址是交付没有问题。现在,出于测试目的,我不会点击链接来验证电子邮件,但是,如果我打开应用程序,我可以访问并执行任何操作。我不确定我错过了什么或者我做错了什么。过去几天我一直被这个困扰着。非常感谢任何帮助。 我的代码 预期结果 新创建的用户应该不能登录和打开应用程序,除非电子邮件得到验证。

  • 我目前已经设置了下面的Auth组件,它工作得很好,但是我的客户现在希望能够为用户提供使用用户名或电子邮件地址登录的选项。 我当前的设置: 我如何才能更改此项,以便日志需要“电子邮件”或新字段“用户名”。 我会假设一个OR语句,但是下面的不工作:

  • 我已经成功地使用 firebase 身份验证实现了电子邮件密码注册,其中我也实施了电子邮件验证。现在,每当用户登录电子邮件验证时,都会被选中,然后只有用户继续。 现在我已经实现了谷歌登录/注册。其中我没有实施电子邮件验证以减少用户的麻烦。但正如我上面所说,每当用户登录电子邮件验证时,只有用户继续前进。 我想要的只是,如果用户用谷歌登录注册,电子邮件应该会被自动验证,而不是用户打开他的帐户来验证帐户

  • 问题内容: 我检查了用户是否通过电子邮件验证。但是,无论我发送并确认了多少电子邮件,验证状态仍为。检查时我做错什么了吗? 问题答案: 我如何实现此功能的方法是添加一个 带有时间间隔的,它将检查用户是否已通过验证,然后在完成验证后终止计时器。 检查您当前用户状态的功能: