Я запускаю пример приложения django из этой библиотеки, здесь весь код.
Я хотел бы добавить часть входа этого приложения, я хочу добавить больше полей в представление входа в систему, но я действительно не понимаю, как это сделать, потому что приложение не имеет своего собственного представления, но оно просто вызов собственного модуля входа в систему. Но что, если я хотел бы использовать эту библиотеку для моего собственного проекта? Буду ли я вынужден использовать их вид входа в систему? Как я могу отредактировать это?
Вот представление входа в систему, которое пример вызывает для обработки аутентификации:
core.py
@class_view_decorator(sensitive_post_parameters())
@class_view_decorator(never_cache)
class LoginView(IdempotentSessionWizardView):
"""
View for handling the login process, including OTP verification.
The login process is composed like a wizard. The first step asks for the
user's credentials. If the credentials are correct, the wizard proceeds to
the OTP verification step. If the user has a default OTP device configured,
that device is asked to generate a token (send sms / call phone) and the
user is asked to provide the generated token. The backup devices are also
listed, allowing the user to select a backup device for verification.
"""
template_name = 'two_factor/core/login.html'
form_list = (
('auth', AuthenticationForm),
('token', AuthenticationTokenForm),
('backup', BackupTokenForm),
)
idempotent_dict = {
'token': False,
'backup': False,
}
def has_token_step(self):
return default_device(self.get_user())
def has_backup_step(self):
return default_device(self.get_user()) and \
'token' not in self.storage.validated_step_data
condition_dict = {
'token': has_token_step,
'backup': has_backup_step,
}
redirect_field_name = REDIRECT_FIELD_NAME
def __init__(self, **kwargs):
super(LoginView, self).__init__(**kwargs)
self.user_cache = None
self.device_cache = None
def post(self, *args, **kwargs):
"""
The user can select a particular device to challenge, being the backup
devices added to the account.
"""
# Generating a challenge doesn't require to validate the form.
if 'challenge_device' in self.request.POST:
return self.render_goto_step('token')
return super(LoginView, self).post(*args, **kwargs)
def done(self, form_list, **kwargs):
"""
Login the user and redirect to the desired page.
"""
login(self.request, self.get_user())
redirect_to = self.request.POST.get(
self.redirect_field_name,
self.request.GET.get(self.redirect_field_name, '')
)
if not is_safe_url(url=redirect_to, allowed_hosts=[self.request.get_host()]):
redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL)
device = getattr(self.get_user(), 'otp_device', None)
if device:
signals.user_verified.send(sender=__name__, request=self.request,
user=self.get_user(), device=device)
return redirect(redirect_to)
def get_form_kwargs(self, step=None):
"""
AuthenticationTokenForm requires the user kwarg.
"""
if step == 'auth':
return {
'request': self.request
}
if step in ('token', 'backup'):
return {
'user': self.get_user(),
'initial_device': self.get_device(step),
}
return {}
def get_device(self, step=None):
"""
Returns the OTP device selected by the user, or his default device.
"""
if not self.device_cache:
challenge_device_id = self.request.POST.get('challenge_device', None)
if challenge_device_id:
for device in backup_phones(self.get_user()):
if device.persistent_id == challenge_device_id:
self.device_cache = device
break
if step == 'backup':
try:
self.device_cache = self.get_user().staticdevice_set.get(name='backup')
except StaticDevice.DoesNotExist:
pass
if not self.device_cache:
self.device_cache = default_device(self.get_user())
return self.device_cache
def render(self, form=None, **kwargs):
"""
If the user selected a device, ask the device to generate a challenge;
either making a phone call or sending a text message.
"""
if self.steps.current == 'token':
self.get_device().generate_challenge()
return super(LoginView, self).render(form, **kwargs)
def get_user(self):
"""
Returns the user authenticated by the AuthenticationForm. Returns False
if not a valid user; see also issue #65.
"""
if not self.user_cache:
form_obj = self.get_form(step='auth',
data=self.storage.get_step_data('auth'))
self.user_cache = form_obj.is_valid() and form_obj.user_cache
return self.user_cache
def get_context_data(self, form, **kwargs):
"""
Adds user's default and backup OTP devices to the context.
"""
context = super(LoginView, self).get_context_data(form, **kwargs)
if self.steps.current == 'token':
context['device'] = self.get_device()
context['other_devices'] = [
phone for phone in backup_phones(self.get_user())
if phone != self.get_device()]
try:
context['backup_tokens'] = self.get_user().staticdevice_set\
.get(name='backup').token_set.count()
except StaticDevice.DoesNotExist:
context['backup_tokens'] = 0
if getattr(settings, 'LOGOUT_REDIRECT_URL', None):
context['cancel_url'] = resolve_url(settings.LOGOUT_REDIRECT_URL)
elif getattr(settings, 'LOGOUT_URL', None):
warnings.warn(
"LOGOUT_URL has been replaced by LOGOUT_REDIRECT_URL, please "
"review the URL and update your settings.",
DeprecationWarning)
context['cancel_url'] = resolve_url(settings.LOGOUT_URL)
return context