Источник: https://docs.djangoproject.com/en/1.6/topics/auth/customizing/
Содержание |
Аутентификация, которая поставляется с Django является достаточно хорошей для большинства распространенных случаев, но вы можете иметь потребность, которые не покрываются из коробки по-умолчанию. Чтобы настроить аутентификацию ваших проектов необходимо понимать, какие точки из предоставленной системы являются расширяемыми или заменимы. Этот документ содержит подробную информацию о том, как система авторизации может быть настроена.
Бэкэнды аутентификации обеспечивают расширяемую систему для того, что бы имя пользователя и пароль сохраненные вместе с моделью пользователя, проходили проверку подлинности на другом сервисе, чем по-умолчанию в Джанго.
Вы можете дать вашим моделям пользовательские разрешения, которые могут быть проверены с помощью системы авторизации Джанго.
Вы можете расширить модель пользователя по-умолчанию, или замените ее полностью настроенной моделью.
Другие источники авторизации
У вас может появиться необходимость подключить другой источник аутентификации - то есть, еще один источником имен пользователей и паролей или методов аутентификации.
Например, ваша компания может уже иметь настроенный LDAP, который хранит имя пользователя и пароль для каждого сотрудника. Это создало бы хлопоты как для администратора сети, так и для самих пользователей, если пользователи имели отдельные учетные записи в LDAP и приложений, базирующихся на Django.
Так, для обработки подобных ситуаций, система аутентификации Django позволяет подключить другие источники аутентификации. Вы можете переопределить схему базы данных на основе Django по умолчанию, или вы можете использовать систему по умолчанию в тандеме с другими системами.
Смотрите перенаправление бэкэнда аутентификации для информации о бэкэндах аутентификации, включенных в Django.
Указание бэкэндов авторизации
За кадром, Django поддерживает список "адресов аутентификации", эта утилита проверяет наличие аутентификации. Когда кто-то вызывает
django.contrib.auth.authenticate ()
- как описано в Как войти пользователю - Джанго пытается аутентификации во всех своих адресов аутентификации. Если первый метод проверки подлинности не удается, Джанго попробует второй, и так далее, пока все бэкенды не пытался это сделать.Список адресов аутентификации использовать задается в настройках
AUTHENTICATION_BACKENDS
. Это должно быть кортежем имен путей Python, которые указывают на классы Python, что знают, как проверить подлинность. Эти классы могут быть в любом месте на вашем пути Python.По умолчанию,
AUTHENTICATION_BACKENDS
содержит это:1 |
('django.contrib.auth.backends.ModelBackend',)
|
Это основная базовая программа аутентификации, которая проверяет базу данных пользователей Django и запросы встроенных разрешений. Она не обеспечивает защиту от brute-force атак при любом ограничении скорости механизма. Вы можете либо реализовать собственное ограничение скорости механизма в пользовательской модели аутентификации, или использовать механизмы, предоставляемые большинством веб-серверов.
Просмотр
AUTHENTICATION_BACKENDS
происходит по порядку, так что если то же самое имя пользователя и пароль одинаковы по нескольким адресам, Django остановит обработку на первом положительном совпадении.Заметка:
После того, как проверка подлинности пользователя Django произошла, тот же бэкенд используется для аутентификации пользователя в пользовательской сессии, и вновь использует тот же бэкенд на время этой сессии, когда доступ к себе на проверку подлинности пользователя не требуется. Это фактически означает, что источники аутентификации кэшируются для каждого сеанса, так что если вы изменитеAUTHENTICATION_BACKENDS
, вам необходимо очистить данные сессии, если вам нужно заставить пользователей повторно аутентификацию, используя различные методы. Простой способ сделать это просто выполнитьSession.objects.all().delete().
Новое в Django-1.6:
Если базовая программа вызывает исключение
PermissionDenied
, аутентификация сразу провалится. Django не будет проверять бэкенды, которые следуют за ним.Написание бэкэнда аутентификации
Бэкенд аутентификации является классом, который реализует два необходимых метода:
get_user(user_id)
и authenticate(**credentials)
, а также набор дополнительных разрешений связанных методов авторизации.Метод
get_user
принимает user_id
- который может быть именем пользователя, идентификатор базы данных или чем-либо другим, но должен быть первичным ключом вашего объекта User
- и возвращает объект пользователя.Метод
authenticate
принимает учетные данные в качестве аргументов ключевых слов. Чаще всего, это будет просто выглядеть следующим образом:1 2 3 4 |
class MyBackend(object):
def authenticate(self, username=None, password=None):
# проверка username/password и возврат User
...
|
Но он также может проверить подлинность токена, вот так:
1 2 3 4 |
class MyBackend(object):
def authenticate(self, token=None):
# проверка токена и возврат User.
...
|
В любом случае,
authenticate
должен проверить получаемые учетные данные, и должен вернуть объект User
, который соответствует этим учетным данным, если учетные данные действительны. Если они не действительны, он должен вернуть None
.Система администрирования Django тесно связана с объектом Django
User
, описанного в начале этого документа. В настоящее время, лучший способ справиться с этим, для создания объекта User
Django для каждого пользователя, который существует в вашем бэкэнд (например, в каталоге LDAP, ваша внешняя база данных SQL и т.д.) Вы можете либо написать сценарий, чтобы сделать это заранее, или ваш метод аутентификации может сделать это, когда пользователь входит в первый раз.Вот пример бэкенда, где аунтентификация по переменным имени пользователя и паролю, определенных в файле
settings.py
и создает объект Django User
первый раз, когда пользователь авторизуется:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
from django.conf import settings
from django.contrib.auth.models import User, check_password
class SettingsBackend(object):
"""
Аутентификация по настройкам ADMIN_LOGIN и ADMIN_PASSWORD.
Использование логинного имени и хэша для пороля. Пример:
ADMIN_LOGIN = 'admin'
ADMIN_PASSWORD = 'sha1$4e987$afbcf42e21bd417fb71db8c66b321e9fc33051de'
"""
def authenticate(self, username=None, password=None):
login_valid = (settings.ADMIN_LOGIN == username)
pwd_valid = check_password(password, settings.ADMIN_PASSWORD)
if login_valid and pwd_valid:
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
# Создать нового пользователя. Обратите внимание,
# что мы можем установить любой пароль, так как это
# не будет проверяться; здесь будет пароль из settings.py
user = User(username=username, password='get from settings.py')
user.is_staff = True
user.is_superuser = True
user.save()
return user
return None
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
|
Обращение к авторизации в собственных бэкэндах
Пользовательские бэкенды аутентификации могут предоставлять свои собственные разрешения.
Модель пользователя будет делегировать разрешения подстановки функции (
get_group_permissions()
, get_all_permissions()
, has_perm()
, и has_module_perms()
), для любой бэкенд аутентификации, которая реализует эти функции.Разрешения, выданные пользователю, являются надмножеством всех разрешений, возвращаемых всем бэкендам. То есть, Django предоставляет разрешение для пользователя, что принимает любой бэкэнд.
Простой бэкенд выше могли бы реализовать разрешения для волшебной администратора довольно просто:
1 2 3 4 5 6 7 |
class SettingsBackend(object):
...
def has_perm(self, user_obj, perm, obj=None):
if user_obj.username == settings.ADMIN_LOGIN:
return True
else:
return False
|
Это дает полные права на эксплуатацию пользовательского доступа в приведенном выше примере. Обратите внимание, что в дополнение к таким же аргументов, переданных соответствующих функций
django.contrib.auth.models.User
, что все функции бэкенда авторизации принимают объект пользователя, который может быть и анонимным пользователем, в качестве аргумента.Полная реализация авторизации можно найти в классе
ModelBackend
в django/contrib/auth/backends.py
, который является бэкендом по умолчанию и чаще всего обращается к таблице auth_permission
. Если вы хотите обеспечить пользовательское поведение лишь в части серверной API, вы можете воспользоваться Python-наследованием и создать подкласс ModelBackend
вместо реализации полного API в пользовательском интерфейсе.Авторизация анонимных пользователей
Анонимный пользователь это тот, который не прошел проверку подлинности т.е. он не предоставил ни одного правильного параметры аутентификации. Тем не менее, это не обязательно означает, что он не имеет права что-то делать. На самом базовом уровне, большинство веб-сайтов разрешать анонимов просматривать большую часть пространства, и многие позволяют анонимные комментарии и т.д.Фрэймворк разрешений Django не имеет системы размещения разрешений для анонимных пользователей. Тем не менее, объект пользователя, передаваемый в бэкенд аутентификации может быть объектом
django.contrib.auth.models.AnonymousUser
, позволяя указать бэкенд пользовательского поведения для авторизации анонимных пользователей.Авторизация неактивных пользователей
Неактивным пользователь является тот, кто прошел проверку подлинности, но чей атрибутis_active
установлен в False
. Однако это не означает, что они не имеют права что-то делать. Например, они имеют право активировать свою учетную запись.Поддержка для анонимных пользователей в системе разрешений позволяет сценарии, где анонимные пользователи имеют разрешения сделать что-либо, а неактивные авторизованные пользователи этого не могут.
Не забудьте проверить атрибута пользователя
is_active
в ваших собственных методах разрешений бэкенда.Обработка объектов разрешения
Фреймворк разрешений Django являются основанием для объекта разрешения, хотя его реализации нет в ядре. Это означает, что проверка на объект разрешения всегда будет возвращать значениеFalse
или пустой список (в зависимости от выполненной проверки). Бэкенд аутентификации получит ключевые слова в качестве параметров obj
и user_obj
для каждого объекта, связанные методы авторизации и может вернуть разрешение уровня объекта в зависимости от обстоятельств.Пользовательские разрешения
Чтобы создавать пользовательские разрешения для данной модели объекта, используйте разрешения атрибут Meta модели.
Это пример модели
Task
, создающей три пользовательских разрешения, то есть, действия пользователи могут или не могут делать с экземплярами групп, на специфичные для вашего приложения:1 2 3 4 5 6 7 8 |
class Task(models.Model):
...
class Meta:
permissions = (
("view_task", "Can see available tasks"),
("change_task_status", "Can change the status of tasks"),
("close_task", "Can remove a task by setting its status as closed"),
)
|
Единственное, что оно делает - создет лишние разрешения, когда вы запускаете
manage.py syncdb
. Ваш код отвечает за проверки значения этих разрешений, когда пользователь пытается получить доступ к функциональности, предоставляемой приложением (просмотр задач, изменение статуса задач, закрытие задач.) К приведенному выше примеру: проверки, если пользователь может просматривать задачи:1 |
user.has_perm('app.view_task')
|
Расширение существующей модели пользователя
Есть два способа расширения модели пользователя по умолчанию не подменяя своей собственной моделью. Если изменения вам нужны чисто поведенческие, и не требуют каких-либо изменений того, что хранится в базе данных, вы можете создать прокси-модель, основанную на пользователя. Это позволяет для любого из возможностей, предлагаемых прокси моделей, включая упорядочение умолчанию, пользовательские менеджеров или методов пользовательской модели.
Если вы хотите хранить информацию, относящуюся к пользователю, вы можете использовать модель отношения один-к-одному, содержащей поля для дополнительной информации. Эта модель один-к-одному часто называют моделью профиль, как это могло бы сохранить без аутентификации связанный информацию о пользователе сайта. Например, вы можете создать модель
Employee
:1 2 3 4 5 |
from django.contrib.auth.models import User
class Employee(models.Model):
user = models.OneToOneField(User)
department = models.CharField(max_length=100)
|
Предполагается существование Сотрудник Фред Смит, который имеет модели
User
и Employee
, можно получить доступ к информации, связанной с использованием стандартных конвенций, связанных с моделями в Django:1 2 |
>>> u = User.objects.get(username='fsmith')
>>> freds_department = u.employee.department
|
Чтобы добавить поля модели профиля на страницу администратора (админку), нужно определить
InlineModelAdmin
(для этого примера, мы будем использовать StackedInline
) в admin.py
вашего приложения и добавить его к классу UserAdmin
которая зарегистрирована с классом User
:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
from my_user_profile_app.models import Employee
# Определение встроенного дескриптора администратора для модели Employee
# который действует как одиночный
class EmployeeInline(admin.StackedInline):
model = Employee
can_delete = False
verbose_name_plural = 'employee'
# Определение нового User администратора
class UserAdmin(UserAdmin):
inlines = (EmployeeInline, )
# Перерегистрация UserAdmin
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
|
Эти модели профиля не были особенными - они всего лишь модели Django, которые имеют связь с моделью User один-к-одному. Таким образом, они не создаются автоматически при создании пользователя, но
django.db.models.signals.post_save
может быть использован для создания или обновления связанных моделей в зависимости от обстоятельств.Обратите внимание, что необходимо использовать родственные модели результаты в дополнительных запросов или присоединяется, чтобы получить соответствующие данные, и в зависимости от ваших потребностей подставляя модель пользователя и добавления смежных областях может быть вашим лучшим выбором. Однако существующие ссылки на модели пользователя по умолчанию в приложениях вашего проекта может оправдать дополнительные нагрузки на базы данных.
Устарело в Django 1.5:
Не рекомендуется начиная с версии 1.5: С введением моделей пользовательских USER, использование AUTH_PROFILE_MODULE определить единую модель профиля больше не поддерживается. См. примечания к выпуску Django 1.5 для получения дополнительной информации.
До 1.5 единая модель профиля может быть указана на веб-узле с заходящего AUTH_PROFILE_MODULE со строкой, состоящей из следующих элементов, разделенных точкой:
- Имя приложения (с учетом регистра), в которой определена модель профиля (другими словами, имя, который был принят в manage.py startapp для создания приложения).
- Название модели (без учета регистра) класс.
UserProfile
и был определен внутри приложения с именем accounts
, соответствующая настройка будет выглядеть так:1 |
AUTH_PROFILE_MODULE = 'accounts.UserProfile'
|
Когда модель профиля была определена и указана таким образом, каждый объект
User
будет иметь метод get_profile()
, который возвращает экземпляр модели профиля пользователя, связанной с этим пользователем.Метод
get_profile()
не создает профиль, если он не существует.Подстановка собственной модели пользователя
Новое в Django 1.5:
Некоторые виды проектов могут иметь требования к аутентификации, для которых использование встроенной модели Django
User
не всегда уместно. Например, на некоторых сайтах имеет больше смысла в использовании адреса электронной почты в качестве идентификации маркер вместо имени пользователя.Django позволяет переопределить модель пользователя по умолчанию, указав значение для параметра
AUTH_USER_MODEL
, который ссылается на пользовательскую модель:1 |
AUTH_USER_MODEL = 'myapp.MyUser'
|
Это точечная пара описывает имя приложения Django (которая обязательно должна быть в вашем
INSTALLED_APPS
), и имя модели Django, который вы хотите использовать в качестве модели пользователя.Внимание!
ИзменениеAUTH_USER_MODEL
имеет большое влияние на структуру вашей базы данных. Он изменяет таблицы, которые доступны, и это повлияет на состав внешних ключей и отношения многие-ко-многим. Если вы собираетесь установитьAUTH_USER_MODEL
, вы должны установить его перед первым запускомmanage.py syncdb
.
Если у вас есть существующий проект, и вы хотите перейти на использовании пользовательской модели пользователя, возможно придется воспользоваться помощью инструментов перехода, подобныхSouth
, для облегчения перехода.
Ссылки на модель User
Если вы ссылаетесь на
User
непосредственно (например, ссылаясь на него в качестве внешнего ключа), ваш код не будет работать в проектах, где настройка AUTH_USER_MODEL
была изменена на другую модель User
.get_user_model()
Вместо ссылки наUser
напрямую, вы должны ссылаться на пользовательскую модель с использованиемdjango.contrib.auth.get_user_model()
. Данный метод возвращает текущий активный модель User - модель пользовательского User если она указана, или User иначе.
При определении внешнего ключа или отношения много-ко-многим к моделиUser
, вы должны указать пользовательскую модель с помощью параметраAUTH_USER_MODEL
. Например:
1 2 3 4 5 from django.conf import settings from django.db import models class Article(models.Model): author = models.ForeignKey(settings.AUTH_USER_MODEL)
Указание собственной модели User
Рекомендации по проектированию модели
Подумайте, прежде чем обрабатывать информацию, напрямую не связанную с проверкой подлинности в пользовательском моделиUser
.
Может быть лучше хранить эти данные в модели специальных приложениях сведений о пользователе, которая имеет связь с модельюUser
. Это позволяет каждому приложению указать свои требования к данным пользователей, не рискуя конфликтами с другими приложениями. С другой стороны, запросы на загрузку соответствующей информации будет включать присоединенные базы данных, что может оказать влияние на производительность.
Django ожидает, что Ваша пользовательская модель
User
отвечает некоторым минимальным требованиям.
- Ваша модель должна иметь целый первичный ключ.
- Ваша модель должна иметь одно уникальное поле, которое может использоваться для целей идентификации. Это может быть имя пользователя, адрес электронной почты, или любой другой уникальный атрибут.
- Ваша модель должна обеспечивать способ решения пользователя в "короткий" и "длинного" форме. Наиболее распространенным вариантом этого было бы использовать данное имя пользователя как "короткий" идентификатор, и полное имя пользователя как "длинный" идентификатор. Тем не менее, нет никаких ограничений на то, что бы вернуть эти два метода - если вы хотите, они могут вернуть точно такие же значения.
User
наследовать от AbstractBaseUser
. AbstractBaseUser
обеспечивает основы внедрения модели User
, в том числе хэши паролей, разбивание на лексемы и сброс пароля. После этого вы должны предоставить некоторые ключевые детали реализации:class
models.CustomUser
USERNAME_FIELD
Строка, описывающая имя поля модели
User
, которая используется в качестве уникального идентификатора. Это, как правило, какое-то имя пользователя, но он также может быть адресом электронной почты, или любой другой уникальный идентификатор. Поле должно быть уникальным (т.е. имеютunique=True
набор в своем определении).
В следующем примере, полеidentifier
используется в качестве идентифицирующего поля:
1 2 3 4 class MyUser(AbstractBaseUser): identifier = models.CharField(max_length=40, unique=True) ... USERNAME_FIELD = 'identifier'
REQUIRED_FIELDS
Список имен полей, которые будет предложено ввести при создании пользователя с помощью команды управления
createsuperuser
. Пользователю будет предложено ввести значение для каждого из этих полей. Он должен включать в себя любое поле, для которого по умолчанию имеет значение ЛОЖЬ или не определено и может включать в себя дополнительные поля, которые вы хотите ввести, когда пользователь создается в интерактивном режиме. Тем не менее, он не будет работать дляForeignKey
полей.REQUIRED_FIELDS
не имеет никакого эффекта в других частях Django, кроме как создание пользователя администратора.
Например, вот частичное определение для моделиUser
, который определяет два обязательных поля - дата рождения и рост:
1 2 3 4 5 6 class MyUser(AbstractBaseUser): ... date_of_birth = models.DateField() height = models.FloatField() ... REQUIRED_FIELDS = ['date_of_birth', 'height']
Заметка
REQUIRED_FIELDS
должен содержать все обязательные поля для вашей модели пользователя, но не должен содержатьUSERNAME_FIELD
или пароль, так как эти поля всегда будут предложены.
is_active
Логический атрибут, который указывает пользователю, считается ли он "активным". Этот атрибут предоставляется в качестве атрибута
AbstractBaseUser
по умолчанию в значенииTrue
. Как вы решите реализовать - будет зависеть от деталей выбранные вами бэкенда аутонтификации. За подробностями см. документацию по атрибутуis_active
встроенной модели пользователя.
get_full_name()
Более формальный идентификатор для пользователя. Чаще интерпретируется как полное имя пользователя, но это может быть любая строка, которая идентифицирует пользователя.
get_short_name()
Короткий, неформальный идентификатор пользователя. Чаще интерпретируется как первым имя пользователя, но это может быть любая строка, идентифицирующая пользователя в неформальной обстановке. Он также может возвращать то же значение, что и
django.contrib.auth.models.User.get_full_name()
.
Следующие методы доступны для любого подкласса
AbstractBaseUser
:class
models.AbstractBaseUser
get_username()
Возвращает значение поля, назначенного
USERNAME_FIELD
.
is_anonymous()
Всегда возвращает значение
False
. Это способ дифференцироваться от объектовAnonymousUser
. Как правило, вы должны предпочесть использованиеis_authenticated()
для этого метода.
is_authenticated()
Всегда возвращает
True
. Это способ сказать, что пользователь прошел аутентификацию. Это не означает никаких разрешений и не проверяет, активен ли пользователь - это означает только то, что пользователь предоставил правильное имя пользователя и пароль.
set_password(raw_password)
Устанавливает пароль пользователя на введенную сырую строку, заботясь о хэширования паролей. Не сохраняется объектом
AbstractBaseUser
.
Когдаraw_password
не указывается, то пароль будет установлен в непригодном для использования пароля, как будто были использованыset_unusable_password()
.
Изменено в Django 1.6:
В Django 1.4 и 1.5, пустая строка так же непреднамеренно сохранялась как unsable пароль.
check_password(raw_password)
Возвращает
True
, если данная сырая строка является правильным паролем для пользователя. (Об этом заботится сравнение хэшированных паролей)
Изменено в Django 1.6:
В Django 1.4 и 1.5, пустая строка была непреднамеренно считается непригодным пароль, в результате чего этот метод возвращения значение False для такого пароль.
set_unusable_password()
Отмечает пользователя, как не имеющиго набора паролей. Это не то же самое, что имеющий пустое строку для ввода пароля.
check_password()
для этого пользователя никогда не вернетсяTrue
. Не сохраняет объектAbstractBaseUser
.
Возможно это понадобится, если принимать аутентификацию для приложения из существующего внешнего источника, например каталога LDAP.
has_usable_password()
Возвращает
False
, еслиset_unusable_password()
был вызван для этого пользователя.
Вы должны также определить пользовательский менеджер для вашей модели пользователя. Если ваша модель
User
определяет username
, email
, is_staff
, is_active
, is_superuser
, last_login
и date_joined
такие же, как и по умолчанию пользователя Джанго, вы можете просто установить UserManager
Джанго; Однако, если ваша модель User
определяет различные поля, вам нужно будет определить пользовательский менеджер, который расширяет BaseUserManager
обеспечивая два дополнительных метода:class
models.CustomUserManager
create_user(*username_field*, password=None, **other_fields)
Прототип create_user() должен принимать поле
username
, а также все необходимые поля в качестве аргументов. Например, если ваша модель пользователь использует электронную почту как поле имени пользователя, и имеетdate_of_birth
как обязательное поле, тоcreate_user
должен быть определен так:
1 2 3 def create_user(self, email, date_of_birth, password=None): # создать пользователя здесь ...
create_superuser(*username_field*, password, **other_fields)
Прототип
create_superuser()
должен принимать полеusername
, а также все необходимые поля в качестве аргументов. Например, если ваша модель пользователь использует электронную почту как поле имени пользователя, и имеетdate_of_birth
как обязательное поле, тоcreate_superuser
должен быть определен как:
1 2 3 def create_superuser(self, email, date_of_birth, password): # создать суперпользователя здесь ...
В отличие отcreate_user()
,create_superuser()
должен требовать от пользователя ввести пароль.
BaseUserManager
предоставляет следующие вспомогательные методы:class
models.BaseUserManager
normalize_email(email)
Метод класса, который нормализует доменную часть адреса электронной почты в нижний регистр.
get_by_natural_key(username)
Получает экземпляр пользователя, используя содержимое поля, присвоенного
USERNAME_FIELD
.
make_random_password(length=10, allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789')
Возвращает случайное пароль заданной длины и случайную строку из разрешенных символов. Обратите внимание, что значение по умолчанию
allowed_chars
нет букв, которые могут ввести пользователей в заблуждение, в том числе:
- i, l, I, и 1 (строчная буква i, строчная буква L, прописная буква i, и номер один)
- o, O, и 0 (строчная буква о, прописная буква О, и ноль)
Расширение базовой модели User Django
Если вы полностью довольны моделью User Джанго, и вы просто хотите добавить некоторую дополнительную информацию о профиле, вы можете использовать подкласс
django.contrib.auth.models.AbstractUser
и добавить свои пользовательские поля профиля. Этот класс обеспечивает полное осуществление пользователя по умолчанию в качестве абстрактной модели.Пользовательские модели User и встроенные формы аутентификации
Как вы можете ожидать, встроенные формы и представления Django, можно сделать определенные предположения о модели пользователя, что они работают вместе.
Если ваша модель
User
не следует тем же предположениям, то может понадобиться определить замену форме, и передать эту форму в качестве части конфигурации views
аутентификации.
UserCreationForm
Зависит от модели пользователя. Должен быть переписан для любых измененных моделейUser
.UserChangeForm
Зависит от модели пользователя. Должен быть переписан для любых измененных моделейUser
.AuthenticationForm
Работает с любым подклассомAbstractBaseUser
, и будет адаптироваться к использованию поля, определенного вUSERNAME_FIELD
.PasswordResetForm
Предполагается, что модель пользователя имеет целый первичный ключ, имеет поле с именем электронной почты, которое может использоваться для идентификации пользователя и логическое поле с именемis_active
чтобы предотвратить сброс паролей для неактивных пользователей.SetPasswordForm
Работает с любым подклассомAbstractBaseUser
PasswordChangeForm
Работает с любым подклассомAbstractBaseUser
AdminPasswordChangeForm
Работает с любым подклассомAbstractBaseUser
Измененная модель User и django.contrib.admin
Чтобы сделать это легко включить фрэймворк разрешений Джанго в свой собственный класс
User
, Django предоставляет PermissionsMixin
. Это абстрактная модель, которую вы можете включить в иерархию классов для вашей модели пользователя, что дает вам все методы и поля базы данных, необходимые для поддержки модели разрешения Django.PermissionsMixin
предоставляет следующие методы и атрибуты:class
models.PermissionsMixin
is_superuser
Логическое. Обозначает, что данный пользователь имеет все права без явного их присвоения.
get_group_permissions(obj=None)
Возвращает набор строк разрешений, которые пользователь имеет через его/ее группы.
Если объект передается, то возвращает права доступа для групп для конкретно данного объекта.
get_all_permissions(obj=None)
Возвращает набор строк разрешений, которые пользователь имеет как через группы, так и через разрешения пользователя.
Если объект передается, то возвращает права доступа для групп для конкретно данного объекта.
has_perm(perm,obj=None)
Возвращает
True
, если пользователь имеет указанное разрешение, гдеperm
в формате"
(см. разрешения). Если пользователь неактивен, этот метод всегда будет возвращать. " False
.
Если объект передается, метод не будет проверять наличие разрешения для модели, но для конкретного объекта.
has_perms(perm_list,obj=None)
Возвращает
True
, если пользователь имеет каждое из указанных разрешений, где каждыйperm
в формате"
(см. разрешения). Если пользователь неактивен, этот метод всегда будет возвращать. " False
.
Если объект передается, метод не будет проверять наличие разрешения для модели, но для конкретного объекта.
has_module_perms(package_name)
Возвращает
True
, если пользователь имеет все разрешения в данном пакете (метка приложения Django). Если пользователь неактивен, этот метод всегда будет возвращатьFalse
.
ModelBackend
Если вы не включаетеPermissionsMixin
, необходимо убедиться, что вы не вызвать методы разрешения наModelBackend
.ModelBackend
предполагает, что некоторые поля доступны на вашей модели пользователя. Если ваша модельUser
не обеспечивает те поля, вы получите ошибки базы данных, когда вы проверите разрешения.
Пользовательские модели User и модели Proxy
Одним из ограничений пользовательских моделей
User
является то, что установка собственной модели пользователя сломает любую модель Proxy
, которую проходит User
. Модели-посредники должны основываться на конкретном базовом классе; путем определения собственной модели пользователя, вы удалите способность Django надежно идентифицировать базовый класс.Если ваш проект использует модель
Proxy
, необходимо либо изменить прокси под расширенную модель User
, которая используется в настоящее время в вашем проекте, или объединить поведение вашей прокси в ваш подкласс User
.Полные примеры
Вот пример из админ-совместимые приложения пользовательским. Эта модель пользователь использует адрес электронной почты в качестве имени пользователя, и имеет необходимую дату рождения; это не дает проверку разрешений, за рамки простого администратора флаг на учетной записи пользователя. Эта модель будет совместима со всеми встроенными AUTH форм и представлений, для создания пользовательских форм, кроме. Этот пример иллюстрирует, как большинство компонентов работать вместе, но не предназначен для копирования непосредственно в проектах для использования в производстве.
Этот код все будут жить в файле models.py для приложения пользовательский аутентификации:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
from django.db import models
from django.contrib.auth.models import (
BaseUserManager, AbstractBaseUser
)
class MyUserManager(BaseUserManager):
def create_user(self, email, date_of_birth, password=None):
"""
Создание и сохранение пользователя с данной
электронной почтой, датой рождения и паролем.
"""
if not email:
raise ValueError('Users must have an email address')
user = self.model(
email=self.normalize_email(email),
date_of_birth=date_of_birth,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, date_of_birth, password):
"""
Creates and saves a superuser with the given email, date of
birth and password.
"""
user = self.create_user(email,
password=password,
date_of_birth=date_of_birth
)
user.is_admin = True
user.save(using=self._db)
return user
class MyUser(AbstractBaseUser):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
)
date_of_birth = models.DateField()
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
objects = MyUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['date_of_birth']
def get_full_name(self):
# The user is identified by their email address
return self.email
def get_short_name(self):
# The user is identified by their email address
return self.email
# On Python 3: def __str__(self):
def __unicode__(self):
return self.email
def has_perm(self, perm, obj=None):
"Does the user have a specific permission?"
# Simplest possible answer: Yes, always
return True
def has_module_perms(self, app_label):
"Does the user have permissions to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True
@property
def is_staff(self):
"Is the user a member of staff?"
# Simplest possible answer: All admins are staff
return self.is_admin
|
Комментариев нет:
Отправить комментарий