Python, Программирование

Реализация аутентификации пользователя в Django/Python

Время прочтения: 4 мин.

Django – это фреймворк для работы с данными с использованием доступа через Web. Один из видов MVC — и называется MVT.

Нередко при реализации модуля администрирования в Django требуется передача пользователю информации о том, что ему дали доступ к серверу с указанием имени пользователя и пароля.

Для таких случаев возможна следующая реализация (использованы Centos 7, Python 2.7, Django 1.11):

  1. Администратор добавляет в систему пользователя, внутри системы генерируется пароль (который не доступен администратору);
  2. Имя и пароль пользователя отправляется на указанный для пользователя почтовый ящик;
  3. Пользователь вводит логин и пароль, ему на ящик или на телефон приходит код доступа, который нужно ввести для дальнейшей аутентификации.  

Для реализации выполним следующие несложные действия:

Необходимо использовать свою модель пользователей, где будут добавлены поля (файл models.py):

  • phone (Номер телефона),
  • is_adm (пользователи поделены на админов и на обычных пользователей),
  • number (временное хранение кода доступа)
class Profile(models.Model):
    username = models.OneToOneField(User)
    phone = models.CharField(verbose_name='Номер телефона',max_length=20, unique=True, db_index=True)
    is_adm = models.BooleanField(verbose_name= 'админ' , default= False)
    number = models.CharField(verbose_name='код', max_length=10, blank=True)    

Изменим вид формы заполнения данных о пользователе, где заранее установим значение пароля по умолчанию равным, например, ‘Aa12345678’ (файл forms.py):

class UserForm(UserCreationForm):
    password1 = forms.CharField(initial='Aa12345678',widget = forms.TextInput(
        attrs={'class':'form-control','type':'password', 'name':'password', 'readonly': True}), #
        label="Пароль")
    password2 = None    

При открытии формы видно, что поле «Пароль» уже заполнено и недоступно для редактирования (серый цвет). Заносим остальные данные и сохраняем.

После нажатия кнопки «Сохранить», пользователь будет создан и ему на почту придет сообщение:

И мы видим, что пароль установлен отличный от пароля по умолчанию.

Это достигается при сохранении данных о пользователе (файл  views.py —  для нового пароля использован генератор случайных чисел):

def form_valid(self, form):
        *********
        passw = 'Zz' + str(randint(100000,999999))
        user.set_password(passw)
        user.save()
        send_mail("Сообщение","Имя пользователя:{}, пароль: {}".format(user.username, passw), settings.EMAIL_HOST_USER, [user.email],fail_silently=False)
        *********

Пользователь, получив сообщение, может уже входить в систему:

Для дальнейшей возможности авторизации у пользователя будет запрошен разовый код:

Который направлен на почтовый ящик:

Или на телефон (здесь имитация реализована через сервис портала smsc.ru, с подключением файла smsc_api.py):

Пользователь вводит код:

И всё получилось:

Код реализации для отправки кода авторизации в файле views.py:,

@login_required(login_url='/core/next')
def next_sms(request):
    if request.user.is_superuser:
        title = 'Главная'
        content = {'title': title}
        return render(request, 'core/index.html', content)
    else:
        title = 'Код СМС'
        content = {'title': title}
        user = User.objects.get(username=request.user)
        profile = Profile.objects.get(username = user.id)
        #if profile.number != '': 
        gen_number = randint(10000,99999)
        profile.number = str(gen_number)
        profile.save()
        # Отправка кода на почтовый ящик
         send_mail("subject","Your code: {}".format(gen_number), settings.EMAIL_HOST_USER, [user.email],fail_silently=False)
        # Отправка кода на телефон
        smsc = SMSC()
        smsc.send_sms(profile.phone, "Your code: {}".format(gen_number), sender = "sms")
        return render(request, 'core/next.html', content)

Для отправки почтовых сообщений вносим необходимые изменения в файл settings.py:

EMAIL_HOST = 'smtp'
EMAIL_PORT = 465
EMAIL_HOST_USER = "пользователь@"
EMAIL_HOST_PASSWORD = "дополнительный_пароль"
EMAIL_USE_SSL = True
SERVER_EMAIL = EMAIL_HOST_USER
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER

Таким образом, внеся небольшие дополнения в код, можно упростить администрирование и обеспечить двухфакторную авторизацию пользователей для более безопасной работы.

Советуем почитать