Django-настройка регистрации без пароля

#django #authentication #registration #django-registration

#django #аутентификация #Регистрация #django-регистрация

Вопрос:

Я пытаюсь создать веб-сайт, где люди вводят только свои адреса электронной почты, и они входят в систему с помощью файлов cookie и всего остального. На более позднем этапе я попрошу их предоставить пароль и имена, но имя пользователя использоваться не будет. Я пытаюсь сделать это с помощью django-registraition, но я получаю ошибки, и у меня есть несколько проблем.

Сначала, чтобы отключить имена пользователей в качестве функции входа, я поставил str (time()) вместо имени пользователя — я искал что-то, что будет меняться каждый раз.

Однако, когда я пропускаю аутентификацию (которая мне в настоящее время не нужна), я получаю сообщение об ошибке:

 'RegistrationProfile' object has no attribute 'backend'
  

В качестве альтернативы я могу оставить аутентификацию, но тогда я не знаю, как аутентифицировать ее только с помощью электронной почты и без пароля. Кроме того, я не знаю, как заставить работать следующую строку:

 auth.login(request, ProfileUser)
  

Если кто-нибудь сможет вытащить меня отсюда, это было бы потрясающе. Вот некоторый код:

мой класс формы:

 class RegistrationFormCustom(forms.Form):
email = forms.EmailField()
def do_save(self):
    new_u = User(username=str(time()),email= self.cleaned_data.get('email'),)
    new_u.save()
    new_p = Profile.objects.create_profile(new_u)
    new_p.save()
    return new_p
  

мое мнение:

 def registerCustom(request, backend, success_url=None, form_class=None,
         disallowed_url='registration_disallowed',
         template_name='registration/registration_form.html',
         extra_context=None,
     initial={}):

form = RegistrationFormCustom(initial=initial)
if request.method == 'POST':
    form = RegistrationFormCustom(initial=initial, data=request.POST)
    if form.is_valid():
        profile = form.do_save()
        profile = auth.authenticate(username = profile.user.email, password = form.cleaned_data.get('pass1'))
        print(profile)
        auth.login(request, profile)
        return redirect('/')

    else:
        pass

return render_jinja(request, 'registration/registration_form.html',
        type="register",
        form = form
        )
  

и я с радостью опубликую любые другие требуемые фрагменты

Ответ №1:

Вы получаете 'RegistrationProfile' object has no attribute 'backend' ошибку, потому что пользователь еще не аутентифицирован. Чтобы авторизовать кого-либо, вы должны сначала вызвать authenticate метод, для которого требуется пароль. Итак, что вы можете сделать вместо этого, это:

 from django.contrib.auth import load_backend, login, logout
from django.conf import settings

def _login_user(request, user):
    """
    Log in a user without requiring credentials (using ``login`` from
    ``django.contrib.auth``, first finding a matching backend).

    """
    if not hasattr(user, 'backend'):
        for backend in settings.AUTHENTICATION_BACKENDS:
            if user == load_backend(backend).get_user(user.pk):
                user.backend = backend
                break
    if hasattr(user, 'backend'):
        return login(request, user)
  

Затем, чтобы авторизовать кого-либо, просто вызовите _login_user функцию с запросом и User моделью. (Вероятно, это будет profile.user в вашем случае) Сделайте это вместо вызова auth.login . Я не уверен, как вы собираетесь определять, является ли это действительным пользователем или нет, без пароля или имени пользователя, но я оставлю это на ваше усмотрение. Если у вас все еще возникают проблемы, дайте мне знать.

Краткое объяснение:

В основном здесь происходит то, что Django требует, чтобы пользователь прошел аутентификацию, чтобы войти в систему с помощью login функции. Эта аутентификация обычно выполняется authenticate функцией, которая требует имя пользователя и пароль и проверяет, соответствует ли предоставленный пароль хэшированной версии в базе данных. Если это произойдет, это добавит серверную часть аутентификации к User модели.

Итак, поскольку у вас нет пароля и имени пользователя, вам просто нужно написать свой собственный метод для добавления серверной части аутентификации в User модель. И это то, что делает моя _login_user ) функция — если пользователь уже аутентифицирован, она просто вызывает login , в противном случае она сначала добавляет серверную часть по умолчанию в User модель, не проверяя правильность имени пользователя и пароля (как authenticate это делает).

Комментарии:

1. Привет, ты моя волшебница кода. С помощью нескольких настроек это действительно выполнило свою работу. Как вы думаете, вы можете объяснить это одним предложением? Кажется, я просто не могу понять, что здесь происходит. Я также искал объяснение того, что такое «серверная часть», но и этого не смог найти

2. Я добавил краткое объяснение, надеюсь, это немного поможет. В Django это немного темное искусство, но я рад, что помог вам продвинуться немного дальше на этом пути.

3. потрясающе. могу я просто спросить вас, что такое серверная часть и что она содержит?

4. @mgPepe: цитируя документы Django, An authentication backend is a class that implements two methods: get_user(user_id) and authenticate(**credentials). Серверные части аутентификации

Ответ №2:

Для других, читающих эту тему, я получил аналогичное сообщение об ошибке, когда я использовал User.objects.create () вместо User.objects.create_user(). По сути, первым методом была установка четкого пароля, тогда как create_user шифрует пароль. Очистить пароли не удастся для аутентификации. Проверьте свою базу данных, если у вас есть пароли, установленные в открытом виде, то, скорее всего, вам нужно использовать create_user() вместо этого.

Запрос автора можно было бы исправить, просто установив пользователя и пароль по умолчанию с помощью create_user() вместо просто user.save().

Ответ №3:

Вы можете создать известный пароль (введите его в settings.py ) и используйте это так, как если бы пользователь ввел его. Создайте пользователя с помощью этого и аутентифицируйте пользователя с помощью этого.