Spec-Zone.ru › Django 1.8

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

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

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

Объекты пользователей

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

Основные атрибуты стандартного пользователя:

  • username
  • password
  • email
  • first_name
  • last_name

См. full API documentation для полного описания, следующая документация ориентирована на задачи.

Создание пользователей

Наиболее прямой способ создания пользователей — использование встроенной функции create_user():

>>> from django.contrib.auth.models import User
>>> user = User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword')

# At this point, user is a User object that has already been saved
# to the database. You can continue to change its attributes
# if you want to change other fields.
>>> user.last_name = 'Lennon'
>>> user.save()

Если у вас установлен Django admin, вы также можете создавать пользователей интерактивно.

Создание суперпользователей

Создайте суперпользователей с помощью команды createsuperuser:

$ python manage.py createsuperuser --username=joe --email=joe@example.com

Вам будет предложено ввести пароль. После его ввода пользователь будет создан сразу. Если вы опустите опцию --username или --email, вам будет предложено ввести эти значения.

Изменение паролей

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

Для изменения пароля пользователя у вас есть несколько вариантов:

manage.py changepassword *username* предлагает способ изменения пароля пользователя из командной строки. Вам будет предложено изменить пароль заданного пользователя, который вы должны ввести дважды. Если они совпадают, новый пароль будет изменен немедленно. Если вы не укажете пользователя, команда попытается изменить пароль пользователя с именем, соответствующим текущему системному пользователю.

Вы также можете изменить пароль программно, используя set_password():

>>> from django.contrib.auth.models import User
>>> u = User.objects.get(username='john')
>>> u.set_password('new password')
>>> u.save()

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

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

Изменение пароля пользователя приведет к выходу из системы всех сеансов, если SessionAuthenticationMiddleware включена. Подробности см. в разделе Недействительность сеанса при изменении пароля.

Авторизация пользователей

authenticate(**credentials) [source]

Для аутентификации заданного имени пользователя и пароля используйте authenticate(). Оно принимает данные в виде ключевых аргументов, для стандартной конфигурации это username и password, и возвращает объект User, если пароль верен для данного имени пользователя. Если пароль неверный, authenticate() возвращает None. Пример:

from django.contrib.auth import authenticate
user = authenticate(username='john', password='secret')
if user is not None:
    # the password verified for the user
    if user.is_active:
        print("User is valid, active and authenticated")
    else:
        print("The password is valid, but the account has been disabled!")
else:
    # the authentication system was unable to verify the username and password
    print("The username and password were incorrect.")

Примечание

Это низкоуровневый способ аутентификации набора учетных данных; например, он используется в RemoteUserMiddleware. Если вы не пишете свою собственную систему аутентификации, вам, вероятно, не потребуется это. Если вам нужно ограничить доступ для авторизованных пользователей, см. декоратор login_required().

Разрешения и авторизация

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

Она используется в Django admin, но вы можете использовать ее и в своем собственном коде.

Django admin использует разрешения следующим образом:

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

Разрешения могут быть заданы не только по типу объекта, но и по конкретному экземпляру объекта. Используя методы has_add_permission(), has_change_permission() и has_delete_permission(), предоставляемые классом ModelAdmin, можно настроить разрешения для различных экземпляров объектов одного типа.

User объекты имеют два поля «многие-ко-многим»: groups и user_permissions. User объекты могут получить доступ к связанным объектам так же, как и любой другой модели Django:

myuser.groups = [group_list]
myuser.groups.add(group, group, ...)
myuser.groups.remove(group, group, ...)
myuser.groups.clear()
myuser.user_permissions = [permission_list]
myuser.user_permissions.add(permission, permission, ...)
myuser.user_permissions.remove(permission, permission, ...)
myuser.user_permissions.clear()

Стандартные разрешения

Когда django.contrib.auth указан в настройке INSTALLED_APPS, это гарантирует, что три стандартных разрешения — «добавление», «изменение» и «удаление» — создаются для каждой модели Django, определенной в одной из установленных вами приложений.

Эти разрешения будут созданы при запуске manage.py migrate; при первом запуске migrate после добавления django.contrib.auth в INSTALLED_APPS, будут созданы стандартные разрешения для всех ранее установленных моделей, а также для любых новых моделей, устанавливаемых в данный момент. После этого, он будет создавать стандартные разрешения для новых моделей каждый раз, когда вы запускаете manage.py migrate (функция, создающая разрешения, связана с сигналом post_migrate).

Предполагая, что у вас есть приложение с app_label foo и моделью с именем Bar, для проверки основных разрешений следует использовать:

  • add: user.has_perm('foo.add_bar')
  • change: user.has_perm('foo.change_bar')
  • delete: user.has_perm('foo.delete_bar')

Модель Permission редко используется напрямую.

Группы

Модели django.contrib.auth.models.Group представляют собой универсальный способ категоризации пользователей, чтобы вы могли применять разрешения или какие-либо другие метки к этим пользователям. Пользователь может принадлежать к любому количеству групп.

Пользователь, входящий в группу, автоматически получает разрешения, предоставленные этой группе. Например, если группа Site editors имеет разрешение can_edit_home_page, любой пользователь этой группы будет иметь это разрешение.

Помимо разрешений, группы являются удобным способом категоризации пользователей, чтобы присвоить им метку или расширить функциональные возможности. Например, вы можете создать группу 'Special users', и вы можете написать код, который, скажем, предоставит им доступ к закрытой части вашего сайта или отправит им закрытые электронные письма.

Программное создание разрешений

Хотя настраиваемые разрешения могут быть определены в классе Meta модели, вы также можете создавать разрешения напрямую. Например, вы можете создать разрешение can_publish для модели BlogPost в myapp:

from myapp.models import BlogPost
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType

content_type = ContentType.objects.get_for_model(BlogPost)
permission = Permission.objects.create(codename='can_publish',
                                       name='Can Publish Posts',
                                       content_type=content_type)

Затем разрешение можно назначить пользователю User через его атрибут user_permissions или группе Group через его атрибут permissions.

Кэширование разрешений

Backend ModelBackend кэширует разрешения на объекте User после первого их получения для проверки разрешений. Это обычно нормально для цикла запрос-ответ, так как разрешения обычно не проверяются сразу после добавления (например, в админке). Если вы добавляете разрешения и проверяете их сразу после этого, например, в тесте или представлении, простейшее решение — повторно получить User из базы данных. Например:

from django.contrib.auth.models import Permission, User
from django.shortcuts import get_object_or_404

def user_gains_perms(request, user_id):
    user = get_object_or_404(User, pk=user_id)
    # any permission check will cache the current set of permissions
    user.has_perm('myapp.change_bar')

    permission = Permission.objects.get(codename='change_bar')
    user.user_permissions.add(permission)

    # Checking the cached permission set
    user.has_perm('myapp.change_bar')  # False

    # Request new instance of User
    user = get_object_or_404(User, pk=user_id)

    # Permission cache is repopulated from the database
    user.has_perm('myapp.change_bar')  # True

    ...

Аутентификация в веб-запросах

Django использует сессии и middleware для подключения системы аутентификации к request objects.

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

Вы можете отличить их с помощью is_authenticated(), например:

if request.user.is_authenticated():
    # Do something for authenticated users.
    ...
else:
    # Do something for anonymous users.
    ...

Как войти в систему

Если у вас есть аутентифицированный пользователь, которого вы хотите прикрепить к текущей сессии, это делается с помощью функции login().

login(request, user) [source]

Чтобы войти в систему пользователя из представления, используйте login(). Она принимает объект HttpRequest и объект User. login() сохраняет идентификатор пользователя в сессии с использованием фреймворка сессий Django.

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

В этом примере показано, как вы можете использовать как authenticate(), так и login():

from django.contrib.auth import authenticate, login

def my_view(request):
    username = request.POST['username']
    password = request.POST['password']
    user = authenticate(username=username, password=password)
    if user is not None:
        if user.is_active:
            login(request, user)
            # Redirect to a success page.
        else:
            # Return a 'disabled account' error message
            ...
    else:
        # Return an 'invalid login' error message.
        ...

Вызов authenticate() в первую очередь

При ручном входе в систему пользователя вы обязательно должны успешно аутентифицировать пользователя с помощью authenticate() перед вызовом login(). authenticate() устанавливает атрибут на объекте User, указывающий, какой аутентификационный backend успешно аутентифицировал этого пользователя (см. документацию по бэкендам бэкендам для получения подробностей), и эта информация потребуется позже во время процесса входа в систему. Будет выведено сообщение об ошибке, если вы попытаетесь войти в систему с объектом пользователя, полученным непосредственно из базы данных.

Как выйти из системы

logout(request) [source]

Чтобы выйти из системы пользователя, вошедшего в систему с помощью django.contrib.auth.login(), используйте django.contrib.auth.logout() в своем представлении. Она принимает объект HttpRequest и не имеет значения возврата. Пример:

from django.contrib.auth import logout

def logout_view(request):
    logout(request)
    # Redirect to a success page.

Обратите внимание, что logout() не выводит никаких ошибок, если пользователь не был авторизован.

При вызове logout() данные сессии текущего запроса полностью очищаются. Все существующие данные удаляются. Это предотвращает использование одного и того же веб-браузера другим человеком для входа и доступа к данным сессии предыдущего пользователя. Если вы хотите добавить что-либо в сессию, что будет доступно пользователю сразу после выхода из системы, сделайте это после вызова django.contrib.auth.logout().

Ограничение доступа для авторизованных пользователей

Прямой способ

Простой способ ограничить доступ к страницам — проверить request.user.is_authenticated() и либо перенаправить на страницу входа:

from django.conf import settings
from django.shortcuts import redirect

def my_view(request):
    if not request.user.is_authenticated():
        return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
    # ...

…или отобразить сообщение об ошибке:

from django.shortcuts import render

def my_view(request):
    if not request.user.is_authenticated():
        return render(request, 'myapp/login_error.html')
    # ...

Декоратор login_required

login_required(redirect_field_name='next', login_url=None) [source]

В качестве короткой записи, вы можете использовать удобный декоратор login_required():

from django.contrib.auth.decorators import login_required

@login_required
def my_view(request):
    ...

login_required() выполняет следующие действия:

  • Если пользователь не авторизован, перенаправить его на settings.LOGIN_URL, передав текущий абсолютный путь в строке запроса. Пример: /accounts/login/?next=/polls/3/.
  • Если пользователь авторизован, выполнить представление обычно. Код представления может свободно предполагать, что пользователь авторизован.

По умолчанию путь, на который пользователь должен быть перенаправлен после успешной авторизации, хранится в параметре строки запроса, называемом "next". Если вы предпочитаете использовать другое имя для этого параметра, login_required() принимает необязательный параметр redirect_field_name:

from django.contrib.auth.decorators import login_required

@login_required(redirect_field_name='my_redirect_field')
def my_view(request):
    ...

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

login_required() также принимает необязательный параметр login_url. Пример:

from django.contrib.auth.decorators import login_required

@login_required(login_url='/accounts/login/')
def my_view(request):
    ...

Обратите внимание, что если вы не указали параметр login_url, вам нужно убедиться, что settings.LOGIN_URL и ваше представление входа корректно связаны. Например, используя значения по умолчанию, добавьте следующие строки в ваш URLconf:

from django.contrib.auth import views as auth_views

url(r'^accounts/login/$', auth_views.login),

settings.LOGIN_URL также принимает имена функций представлений и имена URL-шаблонов. Это позволяет вам свободно переназначать представление входа в вашем URLconf, не обновляя параметр.

Примечание

Декоратор login_required НЕ проверяет флаг is_active пользователя.

Ограничение доступа к авторизованным пользователям, прошедшим проверку

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

Простым способом является запуск вашей проверки на request.user непосредственно в представлении. Например, это представление проверяет, имеет ли пользователь электронную почту в нужном домене, и если нет, перенаправляет его на страницу входа:

from django.shortcuts import redirect

def my_view(request):
    if not request.user.email.endswith('@example.com'):
        return redirect('/login/?next=%s' % request.path)
    # ...
user_passes_test(test_func, login_url=None, redirect_field_name='next') [source]

В качестве короткой записи, вы можете использовать удобный декоратор user_passes_test, который выполняет перенаправление, когда вызываемая функция возвращает False:

from django.contrib.auth.decorators import user_passes_test

def email_check(user):
    return user.email.endswith('@example.com')

@user_passes_test(email_check)
def my_view(request):
    ...

user_passes_test() принимает обязательный аргумент: вызываемую функцию, которая принимает объект User и возвращает True , если пользователю разрешено просматривать страницу. Обратите внимание, что user_passes_test() не проверяет автоматически, что User не анонимный.

user_passes_test() принимает два необязательных аргумента:

login_url
Позволяет указать URL, на который будут перенаправлены пользователи, которые не прошли проверку. Это может быть страница входа и по умолчанию она равна settings.LOGIN_URL, если вы не укажете другую.
redirect_field_name
Аналогично для login_required(). Установка его в значение None удаляет его из URL, что может быть желательно, если вы перенаправляете пользователей, не прошедших проверку, на страницу без входа, где нет параметра «следующая страница».

Например:

@user_passes_test(email_check, login_url='/login/')
def my_view(request):
    ...

Декоратор permission_required

permission_required(perm, login_url=None, raise_exception=False) [source]

Довольно часто нужно проверить, обладает ли пользователь определённым разрешением. По этой причине Django предоставляет удобную для этого короткую запись: декоратор permission_required().:

from django.contrib.auth.decorators import permission_required

@permission_required('polls.can_vote')
def my_view(request):
    ...

Как и для метода has_perm(), имена разрешений имеют вид "<app label>.<permission codename>" (например, polls.can_vote для разрешения на модель в приложении polls).

Обратите внимание, что permission_required() также принимает необязательный параметр login_url . Пример:

from django.contrib.auth.decorators import permission_required

@permission_required('polls.can_vote', login_url='/loginpage/')
def my_view(request):
    ...

Как и в декораторе login_required(), login_url по умолчанию равен settings.LOGIN_URL.

Если параметр raise_exception задан, декоратор будет генерировать исключение PermissionDenied, вызывая представление 403 (HTTP Forbidden) вместо перенаправления на страницу входа.

Если вы хотите использовать raise_exception , но также дать пользователям возможность сначала войти в систему, вы можете добавить декоратор login_required():

from django.contrib.auth.decorators import login_required, permission_required

@login_required
@permission_required('polls.can_vote', raise_exception=True)
def my_view(request):
    ...

Декоратор permission_required() может принимать список разрешений, в этом случае пользователю должны быть предоставлены все разрешения для доступа к представлению.

Применение разрешений к общим представлениям

Для применения разрешения к классовому общему представлению, используйте декоратор для метода View.dispatch в классе. Подробности см. в Декораторы класса. Другой подход — написать миксин, который оборачивает as_view().

Недействительность сессии при смене пароля

Предупреждение

Эта защита применяется только в том случае, если SessionAuthenticationMiddleware включён в MIDDLEWARE_CLASSES. Он включён, если settings.py был создан с помощью startproject в Django ≥ 1.7.

Проверка сессии станет обязательной в Django 1.10 независимо от того, включён ли SessionAuthenticationMiddleware. Если у вас проект до версии 1.7 или он был создан с использованием шаблона, который не включает SessionAuthenticationMiddleware, рассмотрите возможность включения его до этого момента, ознакомившись с замечаниями по обновлению.

END_OF_DOCUMENT_MARKER

Если ваш AUTH_USER_MODEL унаследован от AbstractBaseUser или реализует собственный метод get_session_auth_hash(), аутентифицированные сессии будут содержать хеш, возвращённый этой функцией. В случае с AbstractBaseUser, это HMAC поля пароля. Если включён SessionAuthenticationMiddleware, Django проверяет, что хеш, отправленный вместе с каждым запросом, соответствует хешу, вычисленному на стороне сервера. Это позволяет пользователю выйти из всех сессий, изменив свой пароль.

Стандартные представления изменения пароля, включенные в Django, django.contrib.auth.views.password_change() и представление в админке django.contrib.auth, обновляют сессию с новым хешем пароля, чтобы пользователь, меняющий свой пароль, не выходил из системы. Если у вас есть пользовательское представление изменения пароля и вы хотите получить подобное поведение, используйте эту функцию:

update_session_auth_hash(request, user)

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

from django.contrib.auth import update_session_auth_hash

def password_change(request):
    if request.method == 'POST':
        form = PasswordChangeForm(user=request.user, data=request.POST)
        if form.is_valid():
            form.save()
            update_session_auth_hash(request, form.user)
    else:
        ...

Если вы обновляете существующий сайт и хотите включить этот middleware без необходимости всех пользователей повторно входить в систему, вам следует сначала обновить Django до версии 1.7 и некоторое время использовать его, чтобы при естественном пересоздании сессий при входе пользователей они включали хеш сессии, как описано выше. После начала работы сайта с SessionAuthenticationMiddleware, любые пользователи, которые не вошли в систему и не обновили свою сессию хешем проверки, будут иметь свою существующую сессию недействительной и должны будут войти заново.

Примечание

Так как get_session_auth_hash() основана на SECRET_KEY, обновление сайта с использованием нового секрета сделает все существующие сессии недействительными.

Представления аутентификации

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

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

Использование представлений

Существует несколько способов реализации этих представлений в вашем проекте. Самый простой способ — включить предоставленный URLconf в django.contrib.auth.urls в вашем собственном URLconf, например:

urlpatterns = [
    url('^', include('django.contrib.auth.urls'))
]

Это включит следующие шаблоны URL:

^login/$ [name='login']
^logout/$ [name='logout']
^password_change/$ [name='password_change']
^password_change/done/$ [name='password_change_done']
^password_reset/$ [name='password_reset']
^password_reset/done/$ [name='password_reset_done']
^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$ [name='password_reset_confirm']
^reset/done/$ [name='password_reset_complete']

Представления предоставляют имя URL для более удобной ссылки. Подробнее об использовании именованных шаблонов URL см. документацию по URL.

Если вы хотите больше контроля над своими URL, вы можете обратиться к конкретному представлению в вашем URLconf:

from django.contrib.auth import views as auth_views

urlpatterns = [
    url('^change-password/', auth_views.password_change)
]

Представления имеют необязательные аргументы, которые вы можете использовать для изменения поведения представления. Например, если вы хотите изменить имя шаблона, используемого представлением, вы можете передать аргумент template_name. Способ сделать это — передать ключевые аргументы в URLconf, которые будут переданы в представление. Например:

urlpatterns = [
    url(
        '^change-password/',
        auth_views.password_change,
        {'template_name': 'change-password.html'}
    )
]

Все представления возвращают экземпляр TemplateResponse, что позволяет легко настроить данные ответа перед рендерингом. Способ сделать это — обернуть представление в своё собственное представление:

from django.contrib.auth import views

def change_password(request):
    template_response = views.password_change(request)
    # Do something with `template_response`
    return template_response

Для более подробной информации см. документацию TemplateResponse.

Все представления аутентификации

Вот список всех представлений, которые django.contrib.auth предоставляет. Для деталей реализации см. Использование представлений.

login(request, template_name=`registration/login.html`, redirect_field_name='next', authentication_form=AuthenticationForm, current_app=None, extra_context=None) [source]

Имя URL: login

Подробнее об использовании именованных шаблонов URL см. документацию по URL.

Необязательные аргументы:

  • template_name: Имя шаблона для отображения представления, используемого для входа пользователя. По умолчанию registration/login.html.
  • redirect_field_name: Имя поля GET содержащего URL для переадресации после входа. По умолчанию next.
  • authentication_form: Вызываемый объект (обычно просто класс формы) для аутентификации. По умолчанию AuthenticationForm.
  • current_app: Подсказка, указывающая, в какой приложении находится текущее представление. Подробнее о стратегии разрешения URL с именованными пространствами см. в стратегии разрешения URL с именованными пространствами.
  • extra_context: Словарь данных контекста, который будет добавлен к стандартным данным контекста, передаваемым шаблону.

Вот что делает django.contrib.auth.views.login:

  • Если вызывается через GET, отображается форма входа, отправляющая POST-запрос на тот же URL. Подробнее об этом чуть позже.
  • Если вызывается через POST с предоставленными пользователем учетными данными, он пытается войти в систему. Если вход успешен, представление перенаправляет на URL, указанный в next. Если next не предоставлен, перенаправление происходит на settings.LOGIN_REDIRECT_URL (который по умолчанию /accounts/profile/). Если вход неудачен, отображается форма входа.

Вам необходимо предоставить HTML для шаблона входа, по умолчанию называемого registration/login.html. Этот шаблон получает четыре переменные контекста шаблона:

  • form: Объект Form, представляющий AuthenticationForm.
  • next: URL для переадресации после успешного входа. Он может также содержать строку запроса.
  • site: Текущий Site, в соответствии с настройкой SITE_ID. Если модуль сайтов не установлен, будет установлен экземпляр RequestSite, который получает имя сайта и домен из текущего HttpRequest.
  • site_name: Псевдоним для site.name. Если модуль сайтов не установлен, это будет значение request.META['SERVER_NAME']. Для получения более подробной информации о сайтах см. модуль «сайты».

Если вы предпочитаете не вызывать шаблон registration/login.html, вы можете передать параметр template_name через дополнительные аргументы в представлении в вашем URLconf. Например, эта строка URLconf будет использовать myapp/login.html вместо этого:

url(r'^accounts/login/$', auth_views.login, {'template_name': 'myapp/login.html'}),

Вы также можете указать имя поля GET содержащего URL переадресации после входа, передав redirect_field_name в представление. По умолчанию поле называется next.

Вот пример шаблона registration/login.html, который вы можете использовать в качестве отправной точки. Он предполагает, что у вас есть шаблон base.html, который определяет блок content:

{% extends "base.html" %}

{% block content %}

{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}

{% if next %}
    {% if user.is_authenticated %}
    <p>Your account doesn't have access to this page. To proceed,
    please login with an account that has access.</p>
    {% else %}
    <p>Please login to see this page.</p>
    {% endif %}
{% endif %}

<form method="post" action="{% url 'django.contrib.auth.views.login' %}">
{% csrf_token %}
<table>
<tr>
    <td>{{ form.username.label_tag }}</td>
    <td>{{ form.username }}</td>
</tr>
<tr>
    <td>{{ form.password.label_tag }}</td>
    <td>{{ form.password }}</td>
</tr>
</table>

<input type="submit" value="login" />
<input type="hidden" name="next" value="{{ next }}" />
</form>

{# Assumes you setup the password_reset view in your URLconf #}
<p><a href="{% url 'password_reset' %}">Lost password?</a></p>

{% endblock %}

Если вы настроили аутентификацию (см. Настройка аутентификации), вы можете передать пользовательскую форму аутентификации в представление входа через параметр authentication_form. Эта форма должна принимать аргумент request в своём методе __init__, и предоставить метод get_user(), который возвращает объект аутентифицированного пользователя (этот метод вызывается только после успешной валидации формы).

logout(request, next_page=None, template_name='registration/logged_out.html', redirect_field_name='next', current_app=None, extra_context=None) [source]

Выход пользователя.

Имя URL: logout

Дополнительные аргументы:

  • next_page: URL перенаправления после выхода.
  • template_name: Полное имя шаблона для отображения после выхода пользователя. По умолчанию registration/logged_out.html если не указано.
  • redirect_field_name: Имя поля GET содержащего URL перенаправления после выхода. По умолчанию next. Переопределяет URL перенаправления next_page если передан параметр GET.
  • current_app: Подсказка, указывающая приложение, содержащее текущий вид. См. стратегию разрешения URL с именованными пространствами имён для получения дополнительной информации.
  • extra_context: Словарь данных контекста, который будет добавлен к стандартным данным контекста, передаваемым шаблону.

Контекст шаблона:

  • title: Строка “Выход”, локализованная.
  • site: Текущий Site, согласно настройке SITE_ID. Если модуль сайта не установлен, будет установлено значение RequestSite, которое извлекает имя сайта и домен из текущего HttpRequest.
  • site_name: Псевдоним для site.name. Если модуль сайта не установлен, будет установлено значение request.META['SERVER_NAME']. Дополнительную информацию о сайтах см. в Разделе “sites”.
  • current_app: Подсказка, указывающая приложение, содержащее текущий вид. См. стратегию разрешения URL с именованными пространствами имён для получения дополнительной информации.
  • extra_context: Словарь данных контекста, который будет добавлен к стандартным данным контекста, передаваемым шаблону.
logout_then_login(request, login_url=None, current_app=None, extra_context=None) [source]

Выход пользователя и перенаправление на страницу входа.

Имя URL: Не предоставлено по умолчанию

Дополнительные аргументы:

  • login_url: URL страницы входа, на которую следует перенаправить. По умолчанию settings.LOGIN_URL если не указано.
  • current_app: Подсказка, указывающая приложение, содержащее текущий вид. См. стратегию разрешения URL с именованными пространствами имён для получения дополнительной информации.
  • extra_context: Словарь данных контекста, который будет добавлен к стандартным данным контекста, передаваемым шаблону.
password_change(request, template_name='registration/password_change_form.html', post_change_redirect=None, password_change_form=PasswordChangeForm, current_app=None, extra_context=None) [source]

Изменение пароля пользователя.

Имя URL: password_change

Дополнительные аргументы:

  • template_name: Полное имя шаблона для отображения формы изменения пароля. По умолчанию registration/password_change_form.html если не указано.
  • post_change_redirect: URL для перенаправления после успешного изменения пароля.
  • password_change_form: Пользовательская форма «изменения пароля», которая должна принимать аргумент user. Форма отвечает за фактическое изменение пароля пользователя. По умолчанию PasswordChangeForm.
  • current_app: Подсказка, указывающая приложение, содержащее текущий вид. См. стратегию разрешения URL с именованными пространствами имён для получения дополнительной информации.
  • extra_context: Словарь данных контекста, который будет добавлен к стандартным данным контекста, передаваемым шаблону.

Контекст шаблона:

  • form: Форма изменения пароля (см. password_change_form выше).
password_change_done(request, template_name='registration/password_change_done.html', current_app=None, extra_context=None) [source]

Страница, отображаемая после изменения пользователем пароля.

Имя URL: password_change_done

Дополнительные аргументы:

  • template_name: Полное имя шаблона для использования. По умолчанию registration/password_change_done.html если не указано.
  • current_app: Подсказка, указывающая приложение, содержащее текущий вид. См. стратегию разрешения URL с именованными пространствами имён для получения дополнительной информации.
  • extra_context: Словарь данных контекста, который будет добавлен к стандартным данным контекста, передаваемым шаблону.
password_reset(request, is_admin_site=False, template_name='registration/password_reset_form.html', email_template_name='registration/password_reset_email.html', subject_template_name='registration/password_reset_subject.txt', password_reset_form=PasswordResetForm, token_generator=default_token_generator, post_reset_redirect=None, from_email=None, current_app=None, extra_context=None, html_email_template_name=None) [source]

Позволяет пользователю сбросить свой пароль, сгенерировав одноразовую ссылку для сброса пароля и отправив её на зарегистрированный адрес электронной почты.

Если адрес электронной почты не существует в системе, эта страница не отправит письмо, но пользователю также не будет показано сообщение об ошибке. Это предотвращает утечку информации потенциальным злоумышленникам. Если вы хотите вывести сообщение об ошибке в этом случае, вы можете унаследовать класс PasswordResetForm и использовать аргумент password_reset_form.

Пользователи с неиспользуемым паролем (см. set_unusable_password()) не могут запросить сброс пароля, чтобы предотвратить злоупотребление при использовании внешнего источника аутентификации, например, LDAP. Обратите внимание, что они не получат никакого сообщения об ошибке, так как это раскрыло бы существование их учетной записи, но письмо также не будет отправлено.

Имя URL: password_reset

Необязательные аргументы:

  • template_name: Полное имя шаблона для отображения формы сброса пароля. По умолчанию registration/password_reset_form.html, если не указано.
  • email_template_name: Полное имя шаблона для создания письма со ссылкой на сброс пароля. По умолчанию registration/password_reset_email.html, если не указано.
  • subject_template_name: Полное имя шаблона для темы письма со ссылкой на сброс пароля. По умолчанию registration/password_reset_subject.txt, если не указано.
  • password_reset_form: Форма, которая будет использоваться для получения адреса электронной почты пользователя для сброса пароля. По умолчанию PasswordResetForm.
  • token_generator: Экземпляр класса для проверки одноразовой ссылки. По умолчанию default_token_generator, это экземпляр django.contrib.auth.tokens.PasswordResetTokenGenerator.
  • post_reset_redirect: URL для перенаправления после успешного запроса сброса пароля.
  • from_email: Действительный адрес электронной почты. По умолчанию Django использует DEFAULT_FROM_EMAIL.
  • current_app: Подсказка, указывающая, в каком приложении находится текущий вид. См. стратегию разрешения именованных URL-адресов для получения дополнительной информации.
  • extra_context: Словарь данных контекста, который будет добавлен к стандартным данным контекста, переданным шаблону.
  • html_email_template_name: Полное имя шаблона для создания multipart письма с электронной почтой со ссылкой на сброс пароля. По умолчанию письмо HTML не отправляется.

html_email_template_name был добавлен.

Устаревшее начиная с версии 1.8: Аргумент is_admin_site устарел и будет удален в Django 1.10.

Контекст шаблона:

  • form: Форма (см. password_reset_form выше) для сброса пароля пользователя.

Контекст шаблона письма:

  • email: Псевдоним для user.email
  • user: Текущий User, согласно полю формы email. Только активные пользователи могут сбросить свой пароль (User.is_active is True).
  • site_name: Псевдоним для site.name. Если у вас нет фреймворка сайта, это значение будет установлено в значение request.META['SERVER_NAME']. Дополнительную информацию о сайтах см. в фреймворке «сайты».
  • domain: Псевдоним для site.domain. Если у вас нет фреймворка сайта, это значение будет установлено в значение request.get_host().
  • protocol: http или https
  • uid: Первичный ключ пользователя, закодированный в base 64.
  • token: Токен для проверки того, что ссылка на сброс пароля действительна.

Пример registration/password_reset_email.html (шаблон тела письма):

Someone asked for password reset for email {{ email }}. Follow the link below:
{{ protocol}}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}

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

password_reset_done(request, template_name='registration/password_reset_done.html', current_app=None, extra_context=None) [source]

Страница, отображаемая после того, как пользователю было отправлено письмо со ссылкой на сброс пароля. По умолчанию этот вид вызывается, если у вида password_reset() нет явно заданного URL-адреса для post_reset_redirect.

Имя URL: password_reset_done

Примечание

Если предоставленный адрес электронной почты не существует в системе, пользователь неактивен или имеет неиспользуемый пароль, пользователь все равно будет перенаправлен на этот вид, но письмо не будет отправлено.

Необязательные аргументы:

  • template_name: Полное имя используемого шаблона. По умолчанию registration/password_reset_done.html, если не указано.
  • current_app: Подсказка, указывающая, в каком приложении находится текущий вид. См. стратегию разрешения именованных URL-адресов для получения дополнительной информации.
  • extra_context: Словарь данных контекста, который будет добавлен к стандартным данным контекста, переданным шаблону.
password_reset_confirm(request, uidb64=None, token=None, template_name='registration/password_reset_confirm.html', token_generator=default_token_generator, set_password_form=SetPasswordForm, post_reset_redirect=None, current_app=None, extra_context=None) [source]

Отображает форму для ввода нового пароля.

Имя URL: password_reset_confirm

Необязательные аргументы:

  • uidb64: Идентификатор пользователя, закодированный в base 64. По умолчанию None.
  • token: Токен для проверки того, что пароль действителен. По умолчанию None.
  • template_name: Полное имя шаблона для отображения представления подтверждения пароля. Значение по умолчанию registration/password_reset_confirm.html.
  • token_generator: Экземпляр класса для проверки пароля. По умолчанию default_token_generator, это экземпляр django.contrib.auth.tokens.PasswordResetTokenGenerator.
  • set_password_form: Форма, которая будет использоваться для установки пароля. По умолчанию SetPasswordForm
  • post_reset_redirect: URL для перенаправления после сброса пароля. По умолчанию None.
  • current_app: Подсказка, указывающая, в каком приложении находится текущий вид. См. стратегию разрешения именованных URL-адресов для получения дополнительной информации.
  • extra_context: Словарь данных контекста, который будет добавлен к стандартным данным контекста, переданным шаблону.

Контекст шаблона:

  • form: Форма (см. set_password_form выше) для установки нового пароля пользователя.
  • validlink: Булево значение, True, если ссылка (комбинация uidb64 и token) действительна или ещё не использовалась.
password_reset_complete(request, template_name='registration/password_reset_complete.html', current_app=None, extra_context=None) [source]

Отображает представление, информирующее пользователя о том, что пароль был успешно изменён.

Имя URL: password_reset_complete

Необязательные аргументы:

  • template_name: Полное имя шаблона для отображения представления. По умолчанию registration/password_reset_complete.html.
  • current_app: Подсказка, указывающая, в каком приложении находится текущий вид. См. стратегию разрешения именованных URL-адресов для получения дополнительной информации.
  • extra_context: Словарь данных контекста, который будет добавлен к стандартным данным контекста, переданным шаблону.

Вспомогательные функции

redirect_to_login(next, login_url=None, redirect_field_name='next') [source]

Перенаправляет на страницу входа в систему, а затем обратно на другой URL-адрес после успешного входа в систему.

Обязательные аргументы:

  • next: URL-адрес для перенаправления после успешного входа в систему.

Необязательные аргументы:

  • login_url: URL-адрес страницы входа в систему для перенаправления. По умолчанию settings.LOGIN_URL, если не указано.
  • redirect_field_name: Имя поля GET, содержащего URL для перенаправления после выхода. Переопределяет next при передаче указанного параметра GET.

Встроенные формы

Если вы не хотите использовать встроенные представления, но хотите удобства, не прибегая к написанию форм для этой функциональности, система аутентификации предоставляет несколько встроенных форм, расположенных в django.contrib.auth.forms:

Примечание

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

class AdminPasswordChangeForm [source]

Форма, используемая в интерфейсе администрирования для смены пароля пользователя.

Принимает user в качестве первого позиционного аргумента.

class AuthenticationForm [source]

Форма для входа пользователя.

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

confirm_login_allowed(user) [source]

По умолчанию, AuthenticationForm отклоняет пользователей, у которых флаг is_active установлен в значение False. Вы можете переопределить это поведение с помощью пользовательской политики, определяющей, какие пользователи могут войти. Сделайте это с помощью пользовательской формы, которая наследуется от AuthenticationForm и переопределяет метод confirm_login_allowed(). Этот метод должен вызывать исключение ValidationError, если данный пользователь не может войти.

Например, чтобы разрешить вход всем пользователям независимо от статуса «активный»:

from django.contrib.auth.forms import AuthenticationForm

class AuthenticationFormWithInactiveUsersOkay(AuthenticationForm):
    def confirm_login_allowed(self, user):
        pass

Или чтобы разрешить вход только некоторым активным пользователям:

class PickyAuthenticationForm(AuthenticationForm):
    def confirm_login_allowed(self, user):
        if not user.is_active:
            raise forms.ValidationError(
                _("This account is inactive."),
                code='inactive',
            )
        if user.username.startswith('b'):
            raise forms.ValidationError(
                _("Sorry, accounts starting with 'b' aren't welcome here."),
                code='no_b_users',
            )
class PasswordChangeForm [source]

Форма, позволяющая пользователю изменить свой пароль.

class PasswordResetForm [source]

Форма для генерации и отправки по электронной почте одноразовой ссылки для сброса пароля пользователя.

send_email(subject_template_name, email_template_name, context, from_email, to_email, html_email_template_name=None)

Использует аргументы для отправки EmailMultiAlternatives. Может быть переопределена для настройки того, как электронное письмо отправляется пользователю.

Параметры:
  • subject_template_name – шаблон для темы.
  • email_template_name – шаблон для тела письма.
  • context – контекст, переданный subject_template, email_template, и html_email_template (если он не None).
  • from_email – адрес электронной почты отправителя.
  • to_email – адрес электронной почты получателя.
  • html_email_template_name – шаблон для HTML-тела; по умолчанию None, в этом случае отправляется обычное текстовое письмо.

По умолчанию save() заполняет context теми же переменными, которые password_reset() передает в свой контекст письма.

class SetPasswordForm [source]

Форма, которая позволяет пользователю изменить свой пароль без ввода старого пароля.

class UserChangeForm [source]

Форма, используемая в интерфейсе администрирования для изменения информации и разрешений пользователя.

class UserCreationForm [source]

Форма для создания нового пользователя.

Данные аутентификации в шаблонах

Текущий вошедший пользователь и его разрешения доступны в контексте шаблона при использовании RequestContext.

Техническое замечание

Технически, эти переменные доступны в контексте шаблона только если используется RequestContext и включен процессор контекста 'django.contrib.auth.context_processors.auth'. Он находится в файле настроек по умолчанию. Для более подробной информации см. документацию RequestContext.

Пользователи

При отображении шаблона RequestContext, текущий вошедший пользователь, либо экземпляр User, либо экземпляр AnonymousUser, хранится в переменной шаблона {{ user }}:

{% if user.is_authenticated %}
    <p>Welcome, {{ user.username }}. Thanks for logging in.</p>
{% else %}
    <p>Welcome, new user. Please log in.</p>
{% endif %}

Эта переменная контекста шаблона недоступна, если не используется RequestContext.

Разрешения

Разрешения текущего вошедшего пользователя хранятся в переменной шаблона {{ perms }}. Это экземпляр django.contrib.auth.context_processors.PermWrapper, который является удобным для шаблонов представлением разрешений.

В объекте {{ perms }}, поиск по одному атрибуту является псевдонимом для User.has_module_perms. В данном примере будет отображено True, если вошедший пользователь имеет какие-либо разрешения в приложении foo:

{{ perms.foo }}

Поиск по двум атрибутам является псевдонимом для User.has_perm. В данном примере будет отображено True, если вошедший пользователь имеет разрешение foo.can_vote:

{{ perms.foo.can_vote }}

Таким образом, вы можете проверять разрешения в операторах шаблона {% if %}:

{% if perms.foo %}
    <p>You have permission to do something in the foo app.</p>
    {% if perms.foo.can_vote %}
        <p>You can vote!</p>
    {% endif %}
    {% if perms.foo.can_drive %}
        <p>You can drive!</p>
    {% endif %}
{% else %}
    <p>You don't have permission to do anything in the foo app.</p>
{% endif %}

Также возможно искать разрешения с помощью операторов {% if in %}. Например:

{% if 'foo' in perms %}
    {% if 'foo.can_vote' in perms %}
        <p>In lookup works, too.</p>
    {% endif %}
{% endif %}

Управление пользователями в админпанели

При установленных пакетах django.contrib.admin и django.contrib.auth, админпанель предоставляет удобный способ просмотра и управления пользователями, группами и разрешениями. Пользователей можно создавать и удалять как любые модели Django. Группы можно создавать, а разрешения можно назначать пользователям или группам. Журнал изменений пользователей в моделях, сделанных в админпанели, также хранится и отображается.

Создание пользователей

Вы увидите ссылку на «Пользователи» в разделе «Auth» на главной странице админпанели. Страница администрирования «Добавить пользователя» отличается от стандартных страниц администрирования тем, что требует выбора имени пользователя и пароля перед редактированием остальных полей пользователя.

Обратите внимание: если вы хотите, чтобы учетная запись пользователя могла создавать пользователей через сайт администрирования Django, необходимо предоставить ей разрешения на добавление пользователей и изменение пользователей (т. е. разрешения «Добавить пользователя» и «Изменить пользователя»). Если учетная запись имеет разрешение на добавление пользователей, но не на их изменение, она не сможет добавлять пользователей. Почему? Потому что, если у вас есть разрешение на добавление пользователей, у вас есть возможность создавать суперпользователей, которые затем могут, в свою очередь, изменять других пользователей. Django требует разрешения на добавление и изменение как небольшую меру безопасности.

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

Изменение паролей

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

© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/1.8/topics/auth/default/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API