#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 ) и используйте это так, как если бы пользователь ввел его. Создайте пользователя с помощью этого и аутентифицируйте пользователя с помощью этого.