Изучите систему аутентификации пользователей Django

Оглавление

Введение

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

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

После прочтения этой статьи вы должны иметь твердое понимание того, как Django думает об аутентификации - от пользователей, групп и разрешений. Вы также увидите, как Django играет с безопасностью, где это возможно, чтобы помочь вам избежать непреднамеренного вклада информации о ваших пользователях в "Have I Been Pwned".

Users

Для большинства веб-сайтов основным объектом аутентификации является пользователь. Пользователь идентифицируется некоторой уникальной строкой, которая почти всегда является адресом электронной почты или именем пользователя.

Чтобы доказать, что человек является тем, за кого себя выдает, он должен указать пароль при создании учетной записи, а также в любое время, когда он хочет подтвердить свою подлинность. Это должно быть знакомо: вы проходите через подобный рабочий процесс каждый раз, когда регистрируетесь на таких сервисах, как Twitter или Netflix.

Django предоставляет модель User для создания и управления пользователями. Пользователи Django имеют имя пользователя и пароль, но также могут опционально иметь адрес электронной почты, имя и фамилию:

from django.contrib.auth.models import User
rafaela = User('rafaela', password='$uper$ecretpassword')
# OR
rafaela = User(
    'Rafaela',
    email='rafaela@example.com',
    password='$upser$ecretpassword',
    first_name='Rafaela',
    last_name='Lòpez',
)

Если вы предпочитаете идентифицировать пользователей по их адресам электронной почты, я рекомендую заполнить имя пользователя адресом электронной почты и сохранить адрес в поле email. Это позволит пользователям аутентифицироваться, используя свой адрес электронной почты, и в то же время позволит вам продолжать использовать встроенные в Django функции, связанные с электронной почтой.

Django обеспечивает определенный уровень безопасности, когда речь идет о паролях. Он имеет встроенный набор валидаторов паролей, некоторые из которых включены по умолчанию в новых проектах. Вы можете написать свои собственные валидаторы для применения любых правил паролей, которые вам могут понадобиться, но выбирайте с умом - было показано, что многие правила паролей ведут к снижению безопасности!

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

Хранение паролей в открытом виде - удивительно распространенная оплошность в индустрии, так что пусть Django будет вашим рельсом безопасности!

Подобно другим моделям, которые вы, возможно, использовали в Django, объекты пользователей можно запрашивать, фильтровать и так далее:

User.objects.filter(first_name='Rafaela')

Объекты пользователя имеют несколько других полей, атрибутов и методов, которые будут иметь смысл в контексте, когда вы будете читать дальше о возможностях Django, связанных с пользователями. Давайте начнем с рассмотрения groups.

Группы

Группы Django - это, вкратце, набор пользователей. Пользователи могут принадлежать к нескольким группам, но обратите внимание, что группы не могут принадлежать другим группам - таким образом, это неглубокая иерархия. Группы полезны для создания "категорий" пользователей для любого количества вещей, например, для предоставления определенной группе доступа к какой-либо функции на вашем сайте.

Вы можете создать группу пользователей, просто дав ей имя:

from django.contrib.auth.models import Group
awesome_users = Group.objects.create(name='awesome_users')

Объекты пользователя имеют отношения "многие-ко-многим" с группами, и вы можете получить доступ или установить группы пользователя через его поле groups:

rafaela.groups.add(awesome_users)

Наиболее распространенным использованием групп является их сопряжение с идеей разрешений.

Разрешения

Пользователи не должны иметь права делать на вашем сайте все, что им заблагорассудится. Любой человек может создать аккаунт и удалять чужие сообщения!

Разрешения - это общий способ определения того, может ли пользователь Django выполнять то или иное действие. Разрешения часто определяются по имени приложения и модели Django, хотя это не обязательно так. Вы можете проверить, есть ли у пользователя (или группы, в которую он входит) разрешение действовать с определенным объектом или типом объекта, используя has_perm:

from treats.models import IceCream
if rafaela.has_perm('treats.eat_ice_cream'):
    IceCream.objects.create(eater=rafaela)

Теперь мы знаем, что есть пользователи, которые могут принадлежать к группам, а пользователи и группы могут иметь полномочия на действия с различными типами объектов модели.

Но как выяснить, кто из пользователей кто?

Аутентификация

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

from django.contrib.auth import authenticate
user = authenticate(
    username='rafaela',
    password='$uper$ecretpassword'
)

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

from django.contrib.auth import login
...
if user:
    login(request, user)
else:
    # invalid login, redirect to some kind of error page

После того как пользователь успешно вошел в систему, ему нужен способ остаться вошедшим. Входить в систему при каждой загрузке страницы было бы неприятно! Давайте рассмотрим, как это сделать.

Сессии

Каждый раз, когда пользователь запрашивает страницу на вашем сайте, входящий HTTP-запрос, отправленный из браузера, обрабатывается на нескольких уровнях и в конечном итоге попадает в Django в виде объекта HttpRequest.

Если вы уже писали представление, вы знаете, что одним из его ожидаемых аргументов является объект HttpRequest (обычно называемый request). Если в ваших приложениях и промежуточных компонентах установлены функции аутентификации Django (включенные по умолчанию для новых проектов), запрос будет иметь ссылку на пользователя по адресу request.user.

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

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

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

Итак, как можно определить, вошел ли пользователь в систему?

Обработка аутентифицированных пользователей

Объект запроса всегда будет содержать ссылку на пользователя, поэтому вам нужно уметь различать, что это за пользователь. Вы можете получить базовое представление об этом, проверив атрибут request.user.is_authenticated. Этот атрибут представляет собой булево значение, указывающее, вошел ли пользователь в систему или нет.

Если они не аутентифицированы, request.user будет объектом AnonymousUser, что означает, что человек еще не вошел в систему или, возможно, является первым посетителем. Вы можете использовать различие request.user.is_authenticated для действий, которые разрешено выполнять только вошедшим в систему пользователям.

Заключение

Django имеет обширный набор функций для аутентификации пользователей и взаимодействия с пользовательскими объектами для выполнения задач.

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

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

Вернуться на верх