Я надеюсь, что можно помочь мне изобразить лучший способ реализовать руководство (инициируемая серверная сторона) вход в систему, не используя пароль. Позвольте мне объяснить рабочий процесс:
То, что я пытаюсь сделать, входят в систему пользователь после того, как он нажал ссылку на электронное письмо, таким образом, он может начать использовать веб-сайт сразу же.
Я не могу использовать его пароль, так как он шифруется в DB, единственная опция пишет пользовательский бэкенд аутентификации?
Вам не нужен пароль для входа в систему. Функция auth.login
просто принимает объект User
, который вы, вероятно, уже получаете из базу данных при включении учетной записи. Таким образом, вы можете передать это прямо в логин
.
Конечно, вам нужно быть очень осторожным, чтобы пользователь не мог подделать ссылку на существующую уже включенную учетную запись, которая затем автоматически вошла бы в систему как этот пользователь.
from django.contrib.auth import login
def activate_account(request, hash):
account = get_account_from_hash(hash)
if not account.is_active:
account.activate()
account.save()
user = account.user
login(request, user)
... и т. Д.
Отредактировано :
Хм, не заметил этого требования использовать Authentication
из-за дополнительного свойства, которое оно добавляет. Глядя на код, все, что он делает, - это атрибут backend
, эквивалентный пути к модулю серверной части аутентификации. Таким образом, вы можете просто подделать это - перед вызовом входа в систему, приведенным выше, сделайте следующее:
user.backend = 'django.contrib.auth.backends.ModelBackend'
Ответ Дэниела очень хорош.
Другой способ сделать это - создать HashModelBackend, следуя Custom Authorization backends https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#writing-an-authentication-backend вот так:
class HashModelBackend(object):
def authenticate(self, hash=None):
user = get_user_from_hash(hash)
return user
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
А затем установить это в настройках:
AUTHENTICATION_BACKENDS = (
'myproject.backends.HashModelBackend',
'django.contrib.auth.backends.ModelBackend',
)
Тогда ваше представление будет выглядеть примерно так:
def activate_account(request, hash):
user = authenticate(hash=hash)
if user:
# check if user is_active, and any other checks
login(request, user)
else:
return user_not_found_bad_hash_message