Разное

Авторизация django: Аутентификация пользователя с помощью Django REST Framework и веб-токенов JSON | Статьи о Джанго

Содержание

Как реализовать авторизацию на Django? — Хабр Q&A

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

from django.http import HttpResponse
from django.contrib.auth import authenticate, login
from .forms import LoginForm
from django.shortcuts import render, redirect

def user_login(request):
    if request.method == 'POST':
        form = LoginForm(request.POST)
        if form.is_valid():
            cd = form.cleaned_data
            user = authenticate(username=cd['username'], password=cd['password'])
            if user is not None:
                if user.is_active:
                    login(request, user)
                    return redirect('/')
                else:
                    return HttpResponse('Disabled account')
            else:
                return HttpResponse('Invalid login')
    else:
        form = LoginForm()
    return render(request, 'login/account_login. html', {'form': form})

forms.py

from django import forms


class LoginForm(forms.Form):
    username = forms.CharField()
    password = forms.CharField(widget=forms.PasswordInput)

html

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
</head>
<body>
    <h2>Вход на сайт</h2>
    {% if error %}
        <div>{{ error }}</div>
    {% endif %}
     <form method="post" action="">
         {% csrf_token %}
    <p>
      <label for="login">Логин:</label>
      <input type="text" name="login" >
    </p>

    <p>
      <label for="password">Пароль:</label>
      <input type="password" name="password" >
    </p>

    <p>
      <button type="submit">Войти</button>
    </p>

  </form>
</body>
</html>

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

Django. Авторизация через социальные сети с помощью django-social-auth

27 февраля 2013 г.

Google

Django

Facebook

Авторизация

Социальные сети

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

На своих проектах я использую клёвую библиотеку django-social-auth, до неё пробовал django-ulogin, но сам сервис uLogin мне не понравился (мои сумбурные заметки об этом). На пыхе также обсуждали другие библиотеки, в частности loginza, но отзывы о ней плохие, поэтому даже не пробовал. В любом случае сервисы — это сервисы, и зависимость от сервисов это больше проблема (частые падения сервисов, убогие виджеты и внешний вид без кастомизаций и т.п.) чем зависимость от библиотеки, которая проксирует запросы к конечным «социальным сетям».

Далее будем обсуждать только django-social-auth.

Вообще, нам интересно два репозитория:

  • Основной, от omab;
  • И второй, со свежой поддержкой русских социалок от krvss, в который я пулял фиксы.

Регистрации в сетях

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

Facebook

Зайдите на https://developers.facebook.com/apps/ и нажмите на + Create New App. Введите название приложения (название сайта или проекта), после сабмита формы вы увидите реквизиты «App ID» и «App Secret».

Добавьте их в свой settings.py, пример:

FACEBOOK_APP_ID = '696381432507483'
FACEBOOK_API_SECRET = '15afb0bbeb173aae12e8e875ffccc7a4'

Теперь заполните поле «App Domains», укажите через пробел домены (например один локальный, другой продакшен домен). Поставьте галочку на «Website with Facebook Login» и введите адрес для редиректа, я редиректю в корень продакшен сайта.

Twitter

Зайдите на https://dev.twitter. com/ и введите логин и пароль от вашей учетной записи в Twitter. Далее заходите на https://dev.twitter.com/apps и жмёте на Create a new application, заполните нужные поля и соглашаетесь с правилами, после чего вы получите «Consumer key» и «Consumer secret».

Добавьте их в settings.py, пример:

TWITTER_CONSUMER_KEY = 'G2wMq4KYpTmgZDcjg0EzQ'
TWITTER_CONSUMER_SECRET = 'rGHMGIbOwIEpoxjXzOahc2KmvxY8h20DpZ90LwqEjec'

По умолчанию вам выдадут Access level «Read-only», для авторизации этого вам хватит. Рекомендую прочитать The Application Permission Model.

Вконтакте

Зайдите на страницу http://vk.com/developers.php и нажмите Создать приложение, выберите Тип «Веб-сайт» и введите адрес сайта и имя домена. В ответ получите «ID приложения» и «Защищенный ключ».

Добавьте их в settings.py, пример:

VK_APP_ID = '1234567'
VKONTAKTE_APP_ID = VK_APP_ID
VK_API_SECRET = 'Q0owlQESOXRYd2lcgnLa'
VKONTAKTE_APP_SECRET = VK_API_SECRET

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

Google+

Зайдите на страницу https://code.google.com/apis/console/ , нажмите Create, введите требуемые данные и во вкладке API Access увидите «Client ID» и «Client secret».

Добавьте их в settings.py, пример:

GOOGLE_OAUTh3_CLIENT_ID = '123456789.apps.googleusercontent.com'
GOOGLE_OAUTh3_CLIENT_SECRET = 'p0dJSDjs-dAJsdSAdaSDadasdrt'
GitHub

Зайдите на страницу https://github.com/settings/applications/new и введите логин и пароль от вашей учетной записи в GitHub. Введите имя приложения, адреса сайта для «URL» и «Callback URL» (у меня это один адрес корневой страницы сайта). И получите «Client ID» и «Client Secret», после чего добавьте их в settings.py:

GITHUB_APP_ID = 'da3bad06987041629b96'
GITHUB_API_SECRET = '8bb53dd4a0b1bbc12f77e147c11d5fd6082adb8d'

Теперь перейдем к настройке social_auth.

Установка и настройка django-social-auth

Для начала установим приложение:

pip install django-social-auth

Теперь отредактируйте settings. py:

# Добавляем в AUTHENTICATION_BACKENDS нужные бекенды,
# смотрите полный список https://github.com/omab/django-social-auth/blob/master/doc/configuration.rst
AUTHENTICATION_BACKENDS = (
    'social_auth.backends.twitter.TwitterBackend',
    'social_auth.backends.facebook.FacebookBackend',
    'social_auth.backends.contrib.vk.VKOAuth3Backend',
    'social_auth.backends.google.GoogleOAuth3Backend',
    'social_auth.backends.contrib.github.GithubBackend',
    'django.contrib.auth.backends.ModelBackend',
)

# Добавляем в TEMPLATE_CONTEXT_PROCESSORS процессор "social_auth_by_name_backends"
TEMPLATE_CONTEXT_PROCESSORS = (
    'django.contrib.auth.context_processors.auth',
    'django.core.context_processors.request',
    'social_auth.context_processors.social_auth_by_name_backends',
)

# И добавляем "social_auth" в INSTALLED_APPS
INSTALLED_APPS = (
    ...
    'social_auth',
)

Дополнительные настройки social_auth, добавьте в settings. py:

import random
# Если имя не удалось получить, то можно его сгенерировать
SOCIAL_AUTH_DEFAULT_USERNAME = lambda: random.choice(['Darth_Vader', 'Obi-Wan_Kenobi', 'R2-D2', 'C-3PO', 'Yoda'])
# Разрешаем создавать пользователей через social_auth
SOCIAL_AUTH_CREATE_USERS = True

# Перечислим pipeline, которые последовательно буду обрабатывать респонс 
SOCIAL_AUTH_PIPELINE = (
    # Получает по backend и uid инстансы social_user и user
    'social_auth.backends.pipeline.social.social_auth_user',
    # Получает по user.email инстанс пользователя и заменяет собой тот, который получили выше.
    # Кстати, email выдает только Facebook и GitHub, а Vkontakte и Twitter не выдают
    'social_auth.backends.pipeline.associate.associate_by_email',
    # Пытается собрать правильный username, на основе уже имеющихся данных
    'social_auth.backends.pipeline.user.get_username',
    # Создает нового пользователя, если такого еще нет
    'social_auth.backends.pipeline.user.create_user',
    # Пытается связать аккаунты
    'social_auth. backends.pipeline.social.associate_user',
    # Получает и обновляет social_user.extra_data
    'social_auth.backends.pipeline.social.load_extra_data',
    # Обновляет инстанс user дополнительными данными с бекенда
    'social_auth.backends.pipeline.user.update_user_details'
)

Подключите роуты в urls.py:

urlpatterns = patterns('',
    ...
    url(r'', include('social_auth.urls')),
)

Синхронизация БД:

./manage.py syncdb
./manage.py migrate social_auth

Документацию можно посмотреть тут:

Виджет для вывода кнопочек

Это просто шаблонный inclusion-тег, который выводит ссылочки в виде кнопочек-логотипов социальных сетей, выглядит примерно так:

Сам виджет я не стал публиковать в PyPI, так как не считаю это важным, вам следует просто скопировать исходники отсюда https://github.com/adw0rd/django-social-auth-widget

После чего добавьте в settings. py следующий список:

SOCIAL_AUTH_PROVIDERS = [
    {'id': p[0], 'name': p[1], 'position': {'width': p[2][0], 'height': p[2][1], }}
    for p in (
        ('github', u'Login via GitHub', (0, -70)),
        ('facebook', u'Login via Facebook', (0, 0)),
        ('twitter', u'Login via Twitter', (0, -35)),
    )
]

В вашем шаблоне с формой авторизации использовать так:

{% load social_auth_widget %}

<form action="" method="post">
    <input name="username" />
    <input name="password" />
    <input type="submit" value="Sign in" />
    {% social_auth_widget %}
</form>
Обновление аватарок при авторизации

В статье Django Social Auth: now with images имеется пример как через сигналы обновлять аватарку пользователю, на мой вгляд, код служит только для примера.

Регистрация нового пользователя Django

Все файлы настроек будут храниться в ранее созданном стандартным для django способом проекте registrations. signup/$’, signup, name=’signup’),

]

views.py

from django.contrib.auth import login, authenticate

from .forms import SignUpForm

from django.shortcuts import render, redirect

def signup(request):

    if request.method == ‘POST’:

        form = SignUpForm(request.POST)

        if form.is_valid():#Если форма заполнена правильно

            form.save()#Создаем пользователя

            username = form.cleaned_data.get(‘username’)#с именем

            raw_password = form.cleaned_data.get(‘password1’)# и паролем

            user = authenticate(username=username, password=raw_password)

            login(request, user)

            return redirect(‘index’)#страница редиректа после регистрации

    else:

        form = SignUpForm()

    return render(request, ‘signup.html’, {‘form’: form})

    

В основном то, что мы здесь делаем, это обработка UserCreationForm. После того, как код достигнет form.save(), пользователь будет создан. Но здесь нам нужно сделать еще один шаг: вручную аутентифицировать пользователя. 

Чтобы выполнить аутентификацию, нам нужно захватить необработанный пароль из ввода, который пришел из POST. User.password хранит хэш, и мы не можем использовать его напрямую для аутентификации.

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

signup.html

{% extends ‘base.html’ %}

{% block content %}

  <h3>Регистрация</h3>

  <form method=»post»>

    {% csrf_token %}

    {{ form.as_p }}

    <button type=»submit»>Зарегистрироваться</button>

  </form>

{% endblock %}

На этом простая форма регистрации на django готова

Регистрация с дополнительными полями

Что, если нам надо добавить email пользователя и его полное имя к стандартным полям формы регистрации django. Эта стратегия будет работать, если вы используете Django user как есть без изменений, или если вы расширили его с помощью AbstractUser или AbstractBaseUser.

Далее нам необходимо расширить родную джанговскую форму UserCreationForm

forms.py

from django import forms

from django.contrib.auth.forms import UserCreationForm

from django.contrib.auth.models import User

class SignUpForm(UserCreationForm):

    first_name = forms.CharField(max_length=30, required=False, help_text=’Optional.’)

    last_name = forms.CharField(max_length=30, required=False, help_text=’Optional.’)

    email = forms.EmailField(max_length=254, help_text=’Required. Inform a valid email address.’)

    class Meta:

        model = User

        fields = (‘username’, ‘first_name’, ‘last_name’, ’email’, ‘password1’, ‘password2’, )  

Теперь в представлении нам просто надо изменить класс формы на SignUpForm

views. py

from django.contrib.auth import login, authenticate

from django.shortcuts import render, redirect

from .forms import SignUpForm

def signup(request):

    if request.method == ‘POST’:

        form = SignUpForm(request.POST)

        if form.is_valid():

            form.save()

            username = form.cleaned_data.get(‘username’)

            raw_password = form.cleaned_data.get(‘password1’)

            user = authenticate(username=username, password=raw_password)

            login(request, user)

            return redirect(‘home’)

    else:

        form = SignUpForm()

    return render(request, ‘signup.html’, {‘form’: form})

 

django

Please enable JavaScript to view the comments powered by Disqus.

django-registration Пример | Шпаргалки админа

Мопед не мой, был в песочнице на хабре, потом в кэше гугла, чтоб совсем не потерялся решил оставить себе, был бы у меня инвайт, обязательно выслал, а так пока ещё не заслужил 🙁

В интернете есть много разрозненной информации о django-registration и о расширении стандартной модели Users. Однако, тотального примера, которое позволило бы новичку вникнуть как реализовать задуманную им логику регистрации нет. Я попробовал восполнить этот пробел.

Поставим себе следующие техническое задание:

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

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

Расширение модели User

Расширять модель пользователя мы будем соединением нашей модели Profile с стандартной моделью User посредством поля AutoOneToOneField. Подробнее об этом здесь.

Для начала создадим новое приложение profile:
[cc lang=”python”]django-admin. py startapp profile[/cc]
Заходим в созданную папку profile, и открываем для редактирования файл models.py. В нашем примере, мы расширим модель пользователя полем проффесия, при чем посетитель сайта при регистрации будет выбирать проффесию из списка. Для удобного редактирования этого списка, мы вынесем его в отдельную модель Work. И так, models.py у нас обрастет таким кодом:

[cc lang=”python”]#profile/models.py
# -*- coding: utf-8 -*-
from django.db import models
from django.contrib.auth.models import User
from habr.profile.fields import AutoOneToOneField

class Work(models.Model):
work = models.CharField(max_length = 100, verbose_name = ‘Работа’)

class Profile(models.Model):
user = AutoOneToOneField(User, related_name=’profile’, verbose_name=(‘User’), primary_key=True)
work = models.ForeignKey(Work, verbose_name = ‘Вид деятельности’)
[/cc]

Мы подключаем поле AutoOneToOneField. Создадим в каталоге profile файл fields. py с таким кодом:

[cc lang=”python”]#profile/fields.py
# -*- coding: utf-8 -*-

from django.db.models import OneToOneField
from django.db.models.fields.related import SingleRelatedObjectDescriptor

class AutoSingleRelatedObjectDescriptor(SingleRelatedObjectDescriptor):
def __get__(self, instance, instance_type=None):
try:
return super(AutoSingleRelatedObjectDescriptor, self).__get__(instance, instance_type)
except self.related.model.DoesNotExist:
obj = self.related.model(**{self.related.field.name: instance})
obj.save()
return obj

class AutoOneToOneField(OneToOneField):
def contribute_to_related_class(self, cls, related):
setattr(cls, related.get_accessor_name(), AutoSingleRelatedObjectDescriptor(related))
[/cc]

Осталось добавить приложение в INSTALLED_APPS (файл настроек settings.py), а также указать директиву AUTH_PROFILE_MODULE:

[cc lang=”python”]#settings.py
INSTALLED_APPS = (
##
‘habr. profile’,
##
)
AUTH_PROFILE_MODULE = ‘habr.profile.profile’

[/cc]

Этот этап пройден, выполняем python manage.py syncdb и смотрим как создаются новые таблицы.

Прикручиваем и кастомизируем django-registration

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

Для установки django-registration достаточно просто скачать её отсюда, разархивировать архив и положить папку registration в корневую папку вашего проекта. Однако, так поступать категорически не рекомендуется, лучше воспользоватся утилитами установки easy-install либо pip. Но тут есть один нюанс, если просто выполнить:
[cc lang=”bash”]easy_install -Z django-registration[/cc]

установится версия 0.7, которая не поддерживает очень удобный механизм — сигналы. Поэтому, чтобы посредством easy-install установить последнюю версию 0. accounts/’, include(‘registration.backends.default.urls’)),[/cc]
Теперь для работы осталось только создать шаблоны для регистрации, активации и т.д. Это опять же подробно описано здесь, не будем повторятся.
После этого обновляем базу данных (python manage.py syncdb) и можно тестировать регистрацию. Не забудьте запустить почтовый сервер.

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

Унасследуем стандартную форму модуля django-registration и добавим в неё наши поля. Создаем forms.py в папке profile:

[cc lang=”python”]#profile/forms.py
# -*- coding: utf-8 -*-

from django import forms
from registration.forms import RegistrationFormUniqueEmail
from habr.profile.models import Work

WORK_CHOICES = [
(work.id, work.work) for work in Work.objects.all()
]

class RegistrationFormProfile(RegistrationFormUniqueEmail):
work = forms.ChoiceField(choices=WORK_CHOICES, label = ‘Работа’)

[/cc]
Обратите внимание как заполняется список выбора.accounts/register/$’, ‘registration.views.register’, {‘backend’: ‘registration.backends.default.DefaultBackend’, ‘form_class’:RegistrationFormProfile,},
name=’registration_register’),[/cc]

И имортируем форму:

[cc lang=”python”]from habr.profile.forms import RegistrationFormProfile[/cc]

Раньше приходилось переписывать у формы метод save(), в django-registration 0.8 появилась возможность повесить сигнал на создание юзера. Также сразу повесим сигнал на активацию юзера, для того чтобы сразу провести авторизацию.

Создадим signals.py в папке profile:

[cc lang=”python”]#profile/signals.py
# -*- coding: utf-8 -*-

from registration.signals import user_registered, user_activated
from habr.profile.models import Profile
from forms import RegistrationFormProfile
from django.contrib import auth

def user_created(sender, user, request, **kwargs):
form = RegistrationFormProfile(request.POST)
profile = Profile(user=user, work_id = int(form.accounts/activate/complete/$’, ‘gamb.profile.views.redirect_after_activation’),[/cc]

Техническое задание выполнено!

Python / Django — Авторизация пользователей через социальные сети в джанго

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

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

Что нам понадобиться:

  1. Библиотека Django-Allauth
  2. Django Bootstrap 3
  3. Социальные кнопки или эти
  4. Стили для социальных кнопок

Устанавливаем Django-Allauth согласно инструкции.


pip install django-allauth

В файле Settings.py добавляем все необходимые строки из инструкции и делаем migrate.

Устанавливаем bootstrap и подключаем его в главный шаблон вашего сайта — примерно так.


<link type="text/css" rel="stylesheet" href="{% static 'odrova/bootstrap/css/bootstrap.min.css' %}">

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


<link type="text/css" rel="stylesheet" href="{% static 'odrova/bootstrap-social/bootstrap-social.css' %}">

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


<link type="text/css" rel="stylesheet" href="{% static 'odrova/font-awesome/css/font-awesome.css' %}">

Заходим в админку сайта и там должен быть раздел SOCIAL ACCOUNTS.

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

Добавляем в наш settings.py вконтакте


INSTALLED_APPS = (
    ...
    # The following apps are required:
    'django.contrib.auth',
    'django.contrib.sites',

    'allauth',
    'allauth.account',
    'allauth.socialaccount',
    # ... include the providers you want to enable:
    'allauth.socialaccount.providers.vk',

Далее в админке сайта заходим в социальные приложения и добавляем VK. Но, чтоб его добавить нужно получить id и секретный ключ. Как это сделать, можно посмотреть в инструкции в разделе provaders. В разделе providers находим vk и там будут ссылки на регистрацию своего api.


VK
App registration
    https://vk.com/dev
Development callback URL (“Site address”)
    http://localhost


Переходим по этому адресу https://vk.com/dev и создаем новое приложение. В конечном итоге на выходе у вас должно получиться как у меня на скриншоте ниже. Вы получаете id и секретный ключ.


Далее в админке сайта создаем приложение VK, где и вставляем свой id и секретный ключ.

Ну и в шаблоне выводим примерно так.


  <a href="{% provider_login_url "vk" method="oauth3" %}">
    <span></span>
  </a>

Если у вас остались какие либо вопросы, можете писать тут в комментариях.

Vermus: Ldap авторизация в Django

Вопрос ldap авторизации в Python довольно хорошо рассмотрен. Теперь разберем, как привязать эту авторизацию к Django.
Первый вариант в рамках компании будет регистрация на сайте с django путем авторизации в ldap.
Другой вариант — полная интеграция авторизации ldap в джанго, но тогда все преимущества групп и контроля доступа теряются, если только не получать эту дополнительную информацию от ldap или других источников.
Третий, наиболее гибкий вариант. Отсутствие регистрации. Логиним пользователя — ищем его профиль в auth у Django — если его нет, создаем, если есть — то используем найденный профиль (если пароль в Django не совпадает с ldap паролем — обновляем его).

Давайте пойдем по третьему пути.

Для начала подготавливаем Django. У нас будет расширенный стандартный Django User, так как после авторизации пользователя в ldap мы еще получим его данные с корпоративной базы mssql.

Устанавливаем python-ldap:


$ sudo apt-get install python-ldap

Прописываем в settings.py:


LDAP_DOMAIN='mydomain.com'
LDAP_SERVER='ldaps://%s' % LDAP_DOMAIN #SSL connection

Правим файл auth.py:


# -*- coding: utf-8 -*-

from django.conf import settings
from django.contrib.auth.backends import ModelBackend
from django.core.exceptions import ImproperlyConfigured
from django.db.models import get_model
from social.models import CustomUser

class CustomUserModelBackend(ModelBackend):

def get_local_user(self, email, password=None):

try:
user = self.user_class.objects.get(email=email.lower())
if user.check_password(password):
return user
else:
self.exist_user=user#save user for refresh local data
except self.user_class.DoesNotExist:
return None

def get_ldap_refresh_create_user(self, username=None, password=None):
import ldap, sys

#create new local user
if '@' in username:
#user@domain
LDAP_USERNAME=username
username=username.split('@')[0]
else:
#user
LDAP_USERNAME='%s@%s' % (username, settings.LDAP_DOMAIN)

LDAP_PASSWORD=password

try:
# build a client
ldap_client = ldap.initialize(settings.LDAP_SERVER)
# perform a synchronous bind
ldap_client.simple_bind_s(LDAP_USERNAME, LDAP_PASSWORD)
except ldap.INVALID_CREDENTIALS, e:
return False
except ldap.SERVER_DOWN, e:
return False#@todo raise Validation error

#lpad auth succes:

#try to get local user
user=self.get_local_user(LDAP_USERNAME, password)

if user:#if we check user in localbase
return user
else:#else create new or refresh old pass
if hasattr(self, 'exist_user'):
#refresh local auth data from ldap in case of change pass
self.exist_user.set_password(password)
self.exist_user.save()#write new pass
user=self.exist_user
else:
user=CustomUser.objects.create_user(username,LDAP_USERNAME,password)

return user

def updape_user_info(self, user):
pass

def authenticate(self, username=None, password=None):
#try to auth with ldap
#and refresh user data in success or create new one if user does not exist
user=self.get_ldap_refresh_create_user(username, password)
if user:
self.updape_user_info(user)#get data from mssql
return user
else:
return None# error ldap auth

def get_user(self, user_id):
try:
return self.user_class.objects.get(pk=user_id)
except self.user_class.DoesNotExist:
return None

@property
def user_class(self):
if not hasattr(self, '_user_class'):
#self._user_class = get_model(*settings.CUSTOM_USER_MODEL.split('.', 3))
self._user_class = CustomUser
if not self._user_class:
raise ImproperlyConfigured('Could not get custom user model')
return self._user_class

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

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

Аутентификация — Django REST framework

GitHub

Следующие

Предыдущая

Поиск

Фреймворк Django REST

  • Дом
  • Учебник

    • Быстрый старт
    • 1 — Сериализация
    • 2 — Запросы и ответы
    • 3 — Просмотры на основе классов
    • 4 — Аутентификация и разрешения
    • 5 — Отношения и гиперссылки API
    • 6 — Viewsets и маршрутизаторы
  • Руководство API

    • Запросы
    • Ответы
    • Просмотры
    • Общие представления
    • Наборы просмотров
    • Маршрутизаторы
    • Парсеры
    • Рендереры
    • Сериализаторы
    • Поля сериализатора
    • Отношения сериализатора
    • Валидаторы
    • Аутентификация
    • Разрешения
    • Кеширование
    • Дросселирование
    • Фильтрация
    • Пагинация
    • Управление версиями
    • Согласование содержания
    • Метаданные
    • Схемы
    • Суффиксы формата
    • Возврат URL
    • Исключения
    • Коды состояния
    • Тестирование
    • Настройки
  • Темы

    • Документирование вашего API
    • Клиенты API
    • Интернационализация
    • AJAX, CSRF и CORS
    • HTML и формы
    • Улучшения браузера
    • Доступный для просмотра API
    • ОТДЫХ, гипермедиа и ненависть
  • Сообщество

    • Учебники и ресурсы
    • Сторонние пакеты
    • Участие в REST framework
    • Управление проектом
    • Примечания к выпуску
    • 3.12 Объявление
    • 3.11 Объявление
    • 3.10 Объявление
    • 3.9 Объявление
    • 3.8 Объявление
    • 3.7 Объявление
    • 3.6 Объявление
    • 3.5 Объявление
    • 3.4 Объявление
    • 3.3 Объявление
    • 3.2 Объявление
    • 3.1 Объявление
    • 3.0 Объявление
    • Объявление на Kickstarter
    • Mozilla Grant
    • Финансирование
    • Вакансии

разрешений — Django REST framework

GitHub

Следующие

Предыдущая

Поиск

Фреймворк Django REST

  • Дом
  • Учебник

    • Быстрый старт
    • 1 — Сериализация
    • 2 — Запросы и ответы
    • 3 — Просмотры на основе классов
    • 4 — Аутентификация и разрешения
    • 5 — Отношения и гиперссылки API
    • 6 — Viewsets и маршрутизаторы
  • Руководство API

    • Запросы
    • Ответы
    • Просмотры
    • Общие представления
    • Наборы просмотров
    • Маршрутизаторы
    • Парсеры
    • Рендереры
    • Сериализаторы
    • Поля сериализатора
    • Отношения сериализатора
    • Валидаторы
    • Аутентификация
    • Разрешения
    • Кеширование
    • Дросселирование
    • Фильтрация
    • Пагинация
    • Управление версиями
    • Согласование содержания
    • Метаданные
    • Схемы
    • Суффиксы формата
    • Возврат URL
    • Исключения
    • Коды состояния
    • Тестирование
    • Настройки
  • Темы

    • Документирование вашего API
    • Клиенты API
    • Интернационализация
    • AJAX, CSRF и CORS
    • HTML и формы
    • Улучшения браузера
    • Доступный для просмотра API
    • ОТДЫХ, гипермедиа и ненависть
  • Сообщество

    • Учебники и ресурсы
    • Сторонние пакеты
    • Участие в REST framework
    • Управление проектом
    • Примечания к выпуску
    • 3.12 Объявление
    • 3.11 Объявление
    • 3.10 Объявление
    • 3.9 Объявление
    • 3.8 Объявление
    • 3.7 Объявление
    • 3.6 Объявление
    • 3.5 Объявление
    • 3.4 Объявление
    • 3.3 Объявление
    • 3.2 Объявление
    • 3.1 Объявление
    • 3.0 Объявление
    • Объявление на Kickstarter
    • Mozilla Grant
    • Финансирование
    • Вакансии

Пакеты Django: авторизация

Описание

Разрешения на объект для
Django

Реализация REST системы аутентификации Django
.

Отличная авторизация Django,
без базы данных

JSON Web Token (JWT)
аутентификация для Graphene
Django

Вход OAuth с помощью фреймворка django rest

Войдите в свою цитадель и
сделайте все ваши представления Django
default login_required

Пользовательская модель пользователя для
всех!

🔐 Разрешения ключа API для
Django REST Framework

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

Декларативный доступ
политик / разрешений, смоделированных
после политик AWS IAM.

Регистрация Django и аутентификация
с помощью GraphQL.

Гибкий и масштабируемый сервер авторизации Django
для
унифицированных разрешений для каждого объекта
управления

Django-mfa (Многофакторная аутентификация
) — это простой пакет
для добавления дополнительного уровня безопасности
в ваше приложение django web
.Это …

Заблокируйте сайт Django или
отдельных представлений с настраиваемым предварительным просмотром
и авторизацией

Бэкэнд
аутентификации Django для Microsoft ADFS и
AzureAD

Только техническое обслуживание

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

Django-Access — приложение
, представляющее
, основанное на динамической оценке,
, уровень экземпляра (уровень строки),
, управление правами доступа для
Django

PermissionsX — авторизация
для Django

УСТАРЕЛО: защита входа в систему
на уровне всего сайта

Подписывайте данные с использованием алгоритма шифрования с симметричным ключом
.Проверьте
подписанных данных и определите
возможных ошибок проверки.
Использует sha- (1, 224, 256, 385 и

Дополнение к
django.contrib.auth, которое предоставляет
: приглашения по электронной почте,
представления на основе классов для всех
представлений аутентификации и
правил паролей.

Держите черную ночь в страхе

Инструмент для управления логическими правилами
во всем приложении django
.Логические правила на
мощнее, чем разрешение
или таблицы правил …

Подключаемое приложение Django, которое
позволяет входить / регистрироваться через кошелек
Ethereum (а-ля
CryptoKitties)

Ограничить доступ администратора Django
на основе входящих IP-адресов

Простое и безопасное управление ресурсами AWS среди пользователей IAM
.

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

🤠предоставляет настройку
AnonymousUser в Django

Приложение Django, которое
связывает Группы с Условиями
, требуя согласия от
зарегистрированных участников.

Библиотека Django, которая позволяет
ограничить доступ (пользователю нужен ключ
) к любому сайту django в режиме plug-n-play
.

Утилиты аутентификации Django и авторизации

Реализация Django для
HTTP451

Модуль разрешения
на основе роли джинна

Роли Django с
Role-Group-Permission-User

Django Google Mailer — это пакет Django
, который использует
Gmail API для отправки писем
пользователям в качестве администратора.

Аутентификация JWT для Django
Rest Framework и MongoDB

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

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

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

Пользователь объектов¶

Пользователь объектов являются ядром
система аутентификации. Обычно они представляют людей, взаимодействующих с
ваш сайт и используются для включения таких вещей, как ограничение доступа, регистрация
профили пользователей, связывание контента с создателями и т. д. Только один класс пользователей
существует в структуре аутентификации Django, то есть «суперпользователей» или администраторов «сотрудников» пользователей являются просто объектами пользователей с
набор специальных атрибутов, а не различных классов пользовательских объектов.

Основные атрибуты пользователя по умолчанию:

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

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

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

 >>> от пользователя django.contrib.auth.models import
>>> user = User.objects.create_user ('john', '[email protected]', 'johnpassword')

# На этом этапе пользователь - это объект User, который уже был сохранен
# в базу данных.Вы можете продолжать изменять его атрибуты
# если вы хотите изменить другие поля.
>>> user.last_name = 'Леннон'
>>> user.save ()
 

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

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

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

 $ python manage.py createduperuser --username = joe [email protected]
 

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

Смена паролей¶

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

Чтобы изменить пароль пользователя, у вас есть несколько вариантов:

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

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

 >>> из django.contrib.auth.models импорт пользователя
>>> u = User.objects.get (имя пользователя = 'john')
>>> u.set_password ('новый пароль')
>>> u.save ()
 

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

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

Изменение пароля пользователя приведет к выходу из всех его сеансов. Увидеть
Аннулирование сеанса при смене пароля для подробностей.

Аутентификация пользователей¶

аутентифицировать ( запрос = нет , ** учетные данные ) [источник]

Используйте Authenticate () для проверки набора
учетные данные. Он принимает учетные данные в качестве аргументов ключевого слова, имя пользователя и
пароль для случая по умолчанию, проверяет их по каждому
бэкэнд аутентификации и возвращает
Пользователь объект, если учетные данные
действительно для бэкэнда. Если учетные данные недействительны для какой-либо серверной части или если
бэкэнд вызывает PermissionDenied , это
возвращает Нет .Например:

 из django.contrib.auth импорт аутентификации
пользователь = аутентификация (имя пользователя = 'john', пароль = 'секрет')
если пользователь не None:
    # Серверная часть аутентифицировала учетные данные
еще:
    # Бэкэнд не аутентифицировал учетные данные
 

запрос — необязательный HttpRequest , который
передается методом аутентификации Authenticate () серверной части аутентификации.

Изменено в версии Django Development:

Добавлен необязательный аргумент запроса .

Примечание

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

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

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

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

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

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

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

Пользовательские объекты имеют два типа многие-ко-многим
поля: группы и права_пользователя . Пользователь объектов могут получить доступ к связанным с ними
объекты так же, как и любая другая модель Django:

 myuser.groups.set ([список_групп])
myuser.groups.add (группа, группа, ...)
myuser.groups.remove (группа, группа, ...)
myuser.groups.clear ()
myuser.user_permissions.set ([список_пописок])
myuser.user_permissions.add (разрешение, разрешение, ...)
myuser.user_permissions.remove (разрешение, разрешение, ...)
myuser.user_permissions.clear ()
 

Разрешения по умолчанию¶

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

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

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

  • добавить: user.has_perm ('foo.add_bar')
  • изменение: user.has_perm ('foo.change_bar ')
  • удалить: user.has_perm ('foo.delete_bar')

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

Группы¶

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

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

Помимо разрешений, группы — это удобный способ категоризации пользователей для предоставления
им какой-то ярлык или расширенный функционал. Например, вы можете создать
группа «Специальные пользователи» , и вы могли бы написать код, который мог бы, скажем, дать им
доступ к части вашего сайта, предназначенной только для членов, или отправка им электронной почты только для членов
Сообщения.

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

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

 из myapp.models import BlogPost
из django.contrib.auth.models разрешение на импорт
из django.contrib.contenttypes.models импортировать ContentType

content_type = ContentType.objects.get_for_model (BlogPost)
разрешение = Permission.objects.create (
    codename = 'can_publish',
    name = 'Может публиковать сообщения',
    content_type = content_type,
)
 

Разрешение может быть назначено
Пользователь через его user_permissions
атрибут или Группу через ее
разрешений атрибут.

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

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

 из django.contrib.auth.models Разрешение на импорт, Пользователь
из django.shortcuts импортировать get_object_or_404

def user_gains_perms (запрос, user_id):
    user = get_object_or_404 (Пользователь, pk = user_id)
    # любая проверка разрешений будет кэшировать текущий набор разрешений
    user.has_perm ('myapp.change_bar')

    разрешение = Permission.objects.get (codename = 'change_bar')
    user.user_permissions.add (разрешение)

    # Проверка кешированного набора разрешений
    user.has_perm ('myapp.change_bar') # Ложь

    # Запросить новый экземпляр пользователя
    # Имейте в виду, что user.refresh_from_db () не очищает кеш.
    user = get_object_or_404 (Пользователь, pk = user_id)

    # Кэш разрешений повторно заполняется из базы данных
    user.has_perm ('myapp.change_bar') # Верно

    ...
 

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

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

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

Вы можете отличить их друг от друга с помощью
is_authenticated , вот так:

, если request.user.is_authenticated:
    # Сделайте что-нибудь для аутентифицированных пользователей.
    ...
еще:
    # Сделайте что-нибудь для анонимных пользователей.
    ...
 

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

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

логин ( запрос , пользователь , backend = None ) [источник]

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

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

В этом примере показано, как можно использовать оба
Authenticate () и
логин () :

 из django.contrib.auth импорт аутентификации, логин

def my_view (запрос):
    имя пользователя = запрос.POST ['имя пользователя']
    пароль = request.POST ['пароль']
    пользователь = аутентификация (запрос, имя пользователя = имя пользователя, пароль = пароль)
    если пользователь не None:
        логин (запрос, пользователь)
        # Перенаправить на страницу успеха.
        ...
    еще:
        # Вернуть сообщение об ошибке "неверный логин".
        ...
 

Изменено в Django 1.10:

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

Выбор серверной части аутентификации¶

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

  1. Используйте значение необязательного аргумента backend , если он предоставлен.
  2. Используйте значение атрибута user.backend , если он присутствует. Это позволяет
    соединение Authenticate () и
    логин () :
    Authenticate ()
    устанавливает атрибут user.backend для возвращаемого им объекта User .
  3. Используйте бэкэнд в AUTHENTICATION_BACKENDS , если есть только
    один.
  4. В противном случае вызвать исключение.

В случаях 1 и 2 значение аргумента backend или пользователя .бэкэнд
атрибут должен быть пунктирной строкой пути импорта (например, в
AUTHENTICATION_BACKENDS ), а не фактический серверный класс.

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

выход ( запрос ) [источник]

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

 из django.contrib.auth импорт выхода из системы

def logout_view (запрос):
    выйти из системы (запрос)
    # Перенаправить на страницу успеха.
 

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

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

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

Необработанный путь¶

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

 из настроек импорта django.conf
из django.shortcuts перенаправление импорта

def my_view (запрос):
    если не запрос.user.is_authenticated:
        возврат перенаправления ('% s? next =% s'% (settings.LOGIN_URL, request.path))
    # ...
 

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

 из django.shortcuts import render

def my_view (запрос):
    если не request.user.is_authenticated:
        вернуть рендер (запрос, 'myapp / login_error.html')
    # ...
 
Декоратор login_required
login_required ( redirect_field_name = ‘next’ , login_url = None ) [источник]

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

 из django.contrib.auth.decorators import login_required

@login_required
def my_view (запрос):
    ...
 

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

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

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

 из django.contrib.auth.decorators import login_required

@login_required (redirect_field_name = 'my_redirect_field')
def my_view (запрос):
    ...
 

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

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

 из django.contrib.auth.decorators import login_required

@login_required (login_url = '/ accounts / login /')
def my_view (запрос):
    ...
 

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

 из django.аккаунты / логин / $ ', auth_views.Login.as_view ()),
 

Настройки . LOGIN_URL также принимает функцию просмотра
имена и именованные шаблоны URL. Это позволяет вам
для свободного переназначения представления входа в систему в URLconf без необходимости
обновите настройку.

Примечание

Декоратор login_required НЕ проверяет флаг is_active на
пользователь, но по умолчанию AUTHENTICATION_BACKENDS отклонить неактивно
пользователей.

The LoginRequired mixin¶

При использовании представлений на основе классов вы можете
добиться того же поведения, что и для login_required , используя
LoginRequired Mixin .Этот миксин должен находиться в крайнем левом положении в
список наследования.

class LoginRequired Mixin

Если представление использует этот миксин, все запросы неаутентифицированных пользователей будут
перенаправляться на страницу входа или отображать ошибку HTTP 403 Forbidden,
в зависимости от
raise_exception параметр.

Вы можете установить любой из параметров
AccessMixin для настройки обработки
неавторизованных пользователей:

 из django.contrib.auth.mixins импорт LoginRequiredMixin

класс MyView (LoginRequiredMixin, View):
    login_url = '/ логин /'
    redirect_field_name = 'redirect_to'
 

Примечание

Как и декоратор login_required , этот миксин НЕ проверяет
is_active флаг для пользователя, но по умолчанию
AUTHENTICATION_BACKENDS отклонить неактивных пользователей.

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

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

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

 из django.shortcuts перенаправление импорта

def my_view (запрос):
    если не request.user.email.endswith ('@ example.com'):
        возврат перенаправления ('/ login /? next =% s'% request.path)
    # ...
 
user_passes_test ( test_func , login_url = None , redirect_field_name = ‘next’ ) [источник]

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

 из django.contrib.auth.decorators import user_passes_test

def email_check (пользователь):
    вернуть user.email.endswith ('@ example.com')

@user_passes_test (email_check)
def my_view (запрос):
    ...
 

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

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 (запрос):
    ...
 
класс UserPassesTestMixin

При использовании представлений на основе классов вы
для этого можно использовать UserPassesTestMixin .

test_func () ¶

Вы должны переопределить метод test_func () класса, чтобы
предоставьте выполненный тест. Кроме того, вы можете установить любой из
параметры AccessMixin до
настроить обработку неавторизованных пользователей:

 из django.contrib.auth.mixins импорт UserPassesTestMixin

класс MyView (UserPassesTestMixin, View):

    def test_func (сам):
        вернуть self.request.user.email.endswith ('@ example.com')
 
get_test_func ()

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

Стекинг UserPassesTestMixin

Из-за способа реализации UserPassesTestMixin вы не можете складывать
их в вашем списке наследования.Следующее НЕ работает:

 класс TestMixin1 (UserPassesTestMixin):
    def test_func (сам):
        вернуть self.request.user.email.endswith ('@ example.com')

класс TestMixin2 (UserPassesTestMixin):
    def test_func (сам):
        вернуть self.request.user.username.startswith ('django')

класс MyView (TestMixin1, TestMixin2, View):
    ...
 

Если TestMixin1 вызовет super () и возьмет этот результат в
account, TestMixin1 больше не будет работать автономно.

Декоратор permission_required
permission_required ( perm , login_url = None , raise_exception = False ) [источник]

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

 из django.contrib.auth.decorators import permission_required

@permission_required ('polls.can_vote ')
def my_view (запрос):
    ...
 

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

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

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

 из django.contrib.auth.decorators import permission_required

@permission_required ('polls.can_vote', login_url = '/ loginpage /')
def my_view (запрос):
    ...
 

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

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

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

 из django.contrib.auth.decorators import login_required, permission_required

@login_required
@permission_required ('polls.can_vote', raise_exception = True)
def my_view (запрос):
    ...
 
Требуется разрешение Mixin mixin¶

Чтобы применить проверки разрешений к представлениям на основе классов, вы можете использовать PermissionRequiredMixin :

класс Требуется разрешение Смешивание

Этот миксин, как и permission_required
декоратор, проверяет, все ли данные пользователю, обращающимся к представлению,
разрешения.Вы должны указать разрешение (или итерацию
разрешения) с помощью параметра permission_required :

 из django.contrib.auth.mixins импорт PermissionRequiredMixin

класс MyView (PermissionRequiredMixin, View):
    permission_required = 'polls.can_vote'
    # Или несколько разрешений:
    permission_required = ('polls.can_open', 'polls.can_edit')
 

Вы можете установить любой из параметров
AccessMixin для настройки обработки
неавторизованных пользователей.

Вы также можете переопределить эти методы:

get_permission_required ()

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

has_permission () ¶

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

Перенаправление неавторизованных запросов в представлениях на основе классов¶

Чтобы упростить обработку ограничений доступа в представлениях на основе классов, AccessMixin можно использовать для перенаправления
пользователя на страницу входа или отправьте ответ HTTP 403 Forbidden.

класс AccessMixin
login_url

Возвращаемое значение по умолчанию для get_login_url () .По умолчанию Нет
в этом случае get_login_url () возвращается к
Настройки .LOGIN_URL .

permission_denied_message

Возвращаемое значение по умолчанию для get_permission_denied_message () .
По умолчанию пустая строка.

redirect_field_name

Возвращаемое значение по умолчанию для get_redirect_field_name () . По умолчанию
"следующий" .

raise_exception

Если для этого атрибута установлено значение Истинно ,
PermissionDenied исключение будет
поднял вместо редиректа. По умолчанию Ложь .

get_login_url ()

Возвращает URL-адрес, по которому пользователи, не прошедшие тест, будут перенаправлены
к. Возвращает login_url , если задано, или settings.LOGIN_URL в противном случае.

get_permission_denied_message ()

Когда raise_exception равно Истина , этот метод можно использовать для
контролировать сообщение об ошибке, передаваемое обработчику ошибок для отображения в
Пользователь. Возвращает атрибут permission_denied_message по
по умолчанию.

get_redirect_field_name ()

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

handle_no_permission () ¶

В зависимости от значения raise_exception метод либо вызывает
исключение PermissionDenied или
перенаправляет пользователя на login_url , необязательно включая
redirect_field_name , если он установлен.

Аннулирование сеанса при смене пароля¶

Изменено в Django 1.10:

Проверка сеанса включена и обязательна в Django 1.10 (нет
способ отключить его) независимо от того,
SessionAuthenticationMiddleware включен. В старшем
версиях, эта защита применяется, только если
django.contrib.auth.middleware.SessionAuthenticationMiddleware
включен в MIDDLEWARE .

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

Представления смены пароля по умолчанию, включенные в Django,
PasswordChangeView и
user_change_password просмотр в администраторе django.contrib.auth , обновить
сеанс с новым хешем пароля, чтобы пользователь менял свой
пароль не выйдет из системы.Если у вас есть собственный режим смены пароля
и хотите иметь аналогичное поведение, используйте update_session_auth_hash ()
функция.

update_session_auth_hash ( запрос , пользователь ) [источник]

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

Пример использования:

 из django.contrib.auth импорт update_session_auth_hash

def password_change (запрос):
    если request.method == 'POST':
        form = PasswordChangeForm (пользователь = request.user, data = request.POST)
        если form.is_valid ():
            form.save ()
            update_session_auth_hash (запрос, form.user)
    еще:
        ...
 

Изменено в версии Django Development:

Добавлена ​​ротация сеансового ключа.

просмотров аутентификации¶

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

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

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

Существуют разные методы реализации этих представлений в вашем проекте. В
Самый простой способ — включить предоставленный URLconf в django.contrib.изменить пароль / $ ',
auth_views.PasswordChangeView.as_view (template_name = 'change-password.html'),
),
]

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

Все просмотры аутентификации¶

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

логин ( запрос , template_name = `registration / login.html` , redirect_field_name = 'next' , authentication_form = AuthenticationForm , current_app = None , extra_context = None , redirect_authenticated_user = False ) ¶

Не рекомендуется, начиная с версии 1.11: представление на основе функций входа следует заменить на представление на основе классов
LoginView .

Необязательные аргументы этого представления аналогичны основанным на классах
LoginView атрибутов.Кроме того, в нем:

Не рекомендуется с версии 1.9: атрибут current_app устарел и будет удален в
Django 2.0. Вызывающие должны вместо этого установить request.current_app .

Новое в Django 1.10:

Добавлен параметр redirect_authenticated_user .

класс LoginView

Новое в версии Django Development.

Имя URL: логин

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

Атрибуты:

  • имя_шаблона : имя шаблона для отображения в представлении, используемом для
    войдите в систему. По умолчанию registration / login.html .

  • redirect_field_name : имя поля GET , содержащего
    URL для перенаправления после входа в систему. По умолчанию , затем .

  • authentication_form : вызываемый (обычно просто класс формы) для
    использовать для аутентификации.По умолчанию
    Форма аутентификации .

  • extra_context : словарь контекстных данных, которые будут добавлены в
    данные контекста по умолчанию, передаваемые в шаблон.

  • redirect_authenticated_user : логическое значение, определяющее,
    аутентифицированные пользователи, получающие доступ к странице входа, будут перенаправлены, как если бы
    они только что успешно вошли в систему. По умолчанию Ложь .

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

    Если вы включите redirect_authenticated_user , другие веб-сайты будут
    может определить, аутентифицированы ли их посетители на вашем сайте,
    запрос URL-адресов перенаправления на файлы изображений на вашем веб-сайте.Избегать
    эта информация о «отпечатках пальцев в социальных сетях»
    утечки, разместите все изображения и ваш значок в отдельном домене.

  • success_url_allowed_hosts : A

Настройка аутентификации JWT - Thinkster

Django поставляется с системой аутентификации на основе сеанса, которая работает "из коробки". Он включает в себя все модели, представления и шаблоны, необходимые для того, чтобы пользователи могли войти в систему и создать новую учетную запись. Но вот загвоздка: аутентификация Django работает только с традиционным циклом HTML-запрос-ответ.

Что мы подразумеваем под «традиционным циклом HTML-запрос-ответ»? Исторически сложилось так, что когда пользователь хотел выполнить какое-либо действие (например, создать новую учетную запись), он заполнял форму в своем веб-браузере. Когда они нажимали кнопку «Отправить», браузер отправлял запрос, который включал данные, которые пользователь ввел в регистрационную форму, на сервер, сервер обрабатывал этот запрос, и он отвечал с помощью HTML или перенаправлял браузер. на новую страницу. Это то, что мы имеем в виду, когда говорим о «полном обновлении страницы».«

Почему важно знать, что встроенная аутентификация Django работает только с традиционным циклом HTML-запрос-ответ? Потому что клиент, для которого мы создаем этот API, не придерживается этого цикла. Вместо этого клиент ожидает, что сервер вернет JSON вместо HTML. Возвращая JSON, мы можем позволить клиенту решать, что ему делать дальше, а не серверу. В цикле запрос-ответ JSON сервер получает данные, обрабатывает их и возвращает ответ (как и в цикле запрос-ответ HTML), но ответ не управляет поведением браузера.Он просто сообщает нам результат запроса.

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

Мы углубимся в это позже в этой главе. А пока вот что вы хотите знать:

  1. Мы будем создавать нашу собственную модель User для замены модели Django.
  2. Нам нужно будет написать наши представления для поддержки возврата JSON вместо HTML.
  3. Поскольку мы не будем использовать HTML, нам не нужны встроенные в Django шаблоны входа и регистрации.

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

Аутентификация на основе сеанса

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

В Django сеансы хранятся в виде файлов cookie. Эти сеансы, наряду с некоторым встроенным промежуточным программным обеспечением и объектами запросов, гарантируют, что пользователь будет доступен для каждого запроса.Доступ к пользователю можно получить как запрос . Пользователь . Когда пользователь вошел в систему, request.user является экземпляром класса User . При выходе из системы request.user является экземпляром класса AnonymousUser . Независимо от того, аутентифицирован пользователь или нет, request.user всегда будет существовать.

В чем разница? Проще говоря, в любое время, когда вы хотите узнать, аутентифицируется ли текущий пользователь, вы можете использовать request.user.is_authenticated () , который вернет True , если пользователь аутентифицирован, и False , если нет. Если request.user является экземпляром AnonymousUser , request.user.is_authenticated () всегда будет возвращать False . Это позволяет разработчику (вам!) Преобразовать , если request.user не равно None, и request.user.is_authenticated (): в , если request.user.is_authenticated (): . В этом случае меньше набора текста - это хорошо!

В нашем случае клиент и сервер будут работать в разных местах.Сервер будет работать по адресу http: // localhost: 3000/, а клиент - по адресу http: // localhost: 5000/. Браузер считает, что эти два местоположения находятся в разных доменах, аналогично запуску сервера на http://www.server.com и запуску клиента на http://www.client.com . Мы не будем разрешать внешним доменам доступ к нашим файлам cookie, поэтому нам нужно найти другое альтернативное решение для использования сеансов.

Если вам интересно, почему мы не разрешаем доступ к нашим файлам cookie, вам следует ознакомиться со статьями о совместном использовании ресурсов между источниками (CORS) и подделке межсайтовых запросов (CSRF), ссылки на которые приведены ниже.Если вы просто хотите начать кодирование, установите флажки и двигайтесь дальше.

Аутентификация на основе токенов

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

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

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

Проверочные токены

У нас всегда есть возможность сохранить не только идентификатор пользователя с его токеном.Мы также можем хранить такие вещи, как дата истечения срока действия токена. В этом примере нам нужно убедиться, что этот срок не истек. Если да, значит, токен недействителен. Поэтому мы удаляем его из базы данных и просим пользователя снова войти в систему.

Веб-токенов JSON

JSON Web Token (сокращенно JWT) - это открытый стандарт (RFC 7519), который определяет компактный и автономный способ безопасной передачи информации между двумя сторонами. Вы можете думать о JWT как о токенах аутентификации на стероидах.

Помните, я сказал, что мы будем использовать особую форму аутентификации на основе токенов? Я имел в виду JWT.

Почему веб-токены JSON лучше обычных токенов?

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

  1. JWT - открытый стандарт. Это означает, что все реализации JWT должны быть довольно похожими, что является преимуществом при работе с разными языками и технологиями. Обычные токены имеют более свободную форму, что позволяет разработчику решать, как лучше всего реализовать токены.
  2. JWT могут содержать всю информацию о пользователе, которая удобна для клиента.
  3. Библиотеки берут на себя тяжелую работу здесь. Развертывание собственной аутентификации опасно, поэтому мы оставляем важные вещи проверенным в боях библиотекам, которым мы можем доверять.

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

Как насчет того, чтобы начать?

В файле pipeline / apps / authentication / models.py хранятся модели, которые мы будем использовать для аутентификации.Если вы клонировали репозиторий ранее в этом курсе, вы заметите, что каталог pipeline / apps / authentication / уже существует. Однако файл models.py этого не делает. Вы захотите создать этот файл самостоятельно.

Наши объяснения кода в этом курсе намеренно короткие. Мы уверены, что между комментариями в коде и ресурсами, на которые мы ссылаемся, вы сможете найти нужную информацию.

Создайте канал / apps / authentication / models.py .

Нам понадобится следующий импорт для создания классов User и UserManager , так что продолжайте и добавьте следующее в начало файла:

  импорт jwt

from datetime import datetime, timedelta

из настроек импорта django.conf
из django.contrib.auth.models import (
    AbstractBaseUser, BaseUserManager, PermissionsMixin
)
из моделей импорта django.db
  

При настройке аутентификации в Django одним из требований является указание настраиваемого класса Manager двумя методами: create_user и create_superuser .Чтобы узнать о пользовательской аутентификации в Django, прочтите Подстановку пользовательской модели пользователя.

Начнем с создания класса UserManager .

Введите код для класса UserManager в pipeline / apps / authentication / models.py и обратите внимание на комментарии:

Прочтите «Менеджеры», чтобы узнать, что делает класс Manager .

  класс UserManager (BaseUserManager):
    "" "
    Django требует, чтобы пользовательские пользователи определяли свой собственный класс Manager.От
    наследуя от BaseUserManager, мы получаем много того же кода, что и
    Django для создания пользователя.

    Все, что нам нужно сделать, это переопределить функцию create_user, которую мы будем использовать.
    для создания объектов "Пользователь".
    "" "

    def create_user (собственное имя, имя пользователя, адрес электронной почты, пароль = None):
        "" "Создайте и верните` User` с адресом электронной почты, именем пользователя и паролем. "" "
        если имя пользователя None:
            поднять TypeError ('Пользователи должны иметь имя пользователя.')

        если адрес электронной почты отсутствует:
            Raise TypeError ('Пользователи должны иметь адрес электронной почты.')

        user = self.model (username = username, email = self.normalize_email (электронная почта))
        user.set_password (пароль)
        user.save ()

        возвратный пользователь

    def create_superuser (собственное имя, имя пользователя, адрес электронной почты, пароль):
        "" "
        Создайте и верните `User` с правами суперпользователя (администратора).
        "" "
        если пароль None:
            поднять TypeError ('Суперпользователи должны иметь пароль.')

        user = self.create_user (имя пользователя, адрес электронной почты, пароль)
        user.is_superuser = Верно
        пользователь.is_staff = Верно
        user.save ()

        возвратный пользователь
  

Теперь, когда у нас есть класс менеджера, мы можем создать модель User .

Добавьте модель User в конец файла pipeline / apps / authentication / models.py .

  класс Пользователь (AbstractBaseUser, PermissionsMixin):
    # Каждому `User` нужен понятный человеку уникальный идентификатор, который мы можем использовать для
    # представляют пользователя в пользовательском интерфейсе. Мы хотим проиндексировать этот столбец в
    # база данных для повышения производительности поиска.username = models.CharField (db_index = True, max_length = 255, unique = True)

    # Нам также нужен способ связаться с пользователем и способ идентификации пользователя
    # сами при входе в систему. Поскольку нам нужен адрес электронной почты для связи
    # пользователь в любом случае, мы также будем использовать электронную почту для входа в систему, потому что это
    # наиболее распространенная форма учетных данных на момент написания.
    email = models.EmailField (db_index = True, unique = True)

    # Когда пользователь больше не желает использовать нашу платформу, он может попытаться удалить
    # их аккаунт.Для нас это проблема, потому что собираемые нами данные
    # ценен для нас, и мы не хотим его удалять. Мы
    # просто предложит пользователям способ деактивировать свою учетную запись вместо
    # позволить им удалить его. Таким образом, они больше не будут отображаться на сайте,
    # но мы все еще можем анализировать данные.
    is_active = models.BooleanField (по умолчанию = True)

    # Флаг `is_staff` ожидается от Django, чтобы определить, кто может, а кто не может
    # войдите в админку Django. Для большинства пользователей этот флаг всегда будет
    # ложный.is_staff = models.BooleanField (по умолчанию = False)

    # Отметка времени, представляющая, когда этот объект был создан.
    created_at = models.DateTimeField (auto_now_add = True)

    # Отметка времени, указывающая, когда этот объект был в последний раз обновлен.
    updated_at = models.DateTimeField (auto_now = True)

    # Дополнительные поля, необходимые Django при указании пользовательской модели.

    # Свойство `USERNAME_FIELD` сообщает нам, какое поле мы будем использовать для входа в систему.
    # В данном случае мы хотим, чтобы это было поле электронной почты.
    USERNAME_FIELD = 'электронная почта'
    REQUIRED_FIELDS = ['имя пользователя']

    # Сообщает Django, что класс UserManager, определенный выше, должен управлять
    # объекта этого типа.objects = UserManager ()

    def __str __ (сам):
        "" "
        Возвращает строковое представление этого `User`.

        Эта строка используется, когда в консоли печатается «Пользователь».
        "" "
        вернуть self.email

    @свойство
    токен защиты (сам):
        "" "
        Позволяет нам получить токен пользователя, вызвав user.token вместо
        `user.generate_jwt_token ().

        Декоратор `@ property` выше делает это возможным. `токен` называется
        «динамическое свойство».
        "" "
        вернуть себя._generate_jwt_token ()

    def get_full_name (сам):
        "" "
        Этот метод требуется Django для таких вещей, как обработка электронной почты.
        Обычно это имя и фамилия пользователя. Поскольку мы делаем
        не храним настоящее имя пользователя, вместо этого мы возвращаем его имя пользователя.
        "" "
        вернуть self.username

    def get_short_name (сам):
        "" "
        Этот метод требуется Django для таких вещей, как обработка электронной почты.
        Обычно это имя пользователя.Поскольку мы не храним
        настоящее имя пользователя, вместо этого мы возвращаем его имя пользователя.
        "" "
        вернуть self.username

    def _generate_jwt_token (сам):
        "" "
        Создает веб-токен JSON, в котором хранится идентификатор этого пользователя, срок действия которого истекает.
        дата установлена ​​на 60 дней вперед.
        "" "
        dt = datetime.now () + timedelta (дней = 60)

        token = jwt.encode ({
            'id': self.pk,
            'exp': int (dt.strftime ('% s'))
        }, settings.SECRET_KEY, алгоритм = 'HS256')

        жетон возврата.декодировать ('utf-8')
  

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

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

Указание параметра AUTH_USER_MODEL

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

Настоятельно рекомендуется уделить секунду, чтобы прочитать «Подстановка модели клиента»; особенно разделы «Предупреждение».

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

Расскажите Django о нашей модели User , указав параметр AUTH_USER_MODEL в файле канала / settings .py .

Чтобы установить параметр AUTH_USER_MODEL , введите следующее в нижней части pipeline / settings.py :

  # Сообщите Django о созданной нами пользовательской модели User. Строка
# `authentication.User` сообщает Django, что мы имеем в виду модель` User` в
# модуль `аутентификации`. Этот модуль зарегистрирован выше в настройках
# называется `INSTALLED_APPS`.
AUTH_USER_MODEL = 'аутентификация.Пользователь'
  

Создание и выполнение миграций

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

** Примечание. ** Если вы запустили python manage.py makemigrations или python manage.py migrate , вам необходимо удалить свою базу данных, прежде чем продолжить. Если вы используете SQLite в качестве базы данных, все, что вам нужно сделать, это удалить файл с именем db.sqlite3 в корневом каталоге вашего проекта.

Если вы используете PostgreSQL, следуйте инструкциям ниже:

Если вы уже запустили python manage.py makemigrations или python manage.py migrate , удалите файл db.sqlite3 из корневого каталога вашего проекта. Django будет недоволен, если вы измените AUTH_USER_MODEL после создания базы данных, и лучше всего просто удалить базу данных и начать заново.

Теперь вы готовы создавать и применять миграции.После этого мы можем создать нашего первого пользователя.

Чтобы создать миграции, вам необходимо запустить в консоли следующую команду, чтобы создать миграции:

  python manage.py makemigrations
  

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

Чтобы создать набор миграций для приложения аутентификации , запустите следующее:

  управление питоном.аутентификация py makemigrations
  

Это создаст начальную миграцию для приложения аутентификации . В будущем, когда вы захотите сгенерировать миграции для приложения аутентификации , вам нужно будет только запустить python manage.py makemigrations .

Сделайте миграции по умолчанию, запустив python manage.py makemigrations .

Создайте начальные миграции для приложения аутентификации , запустив python manage.py makemigrations аутентификация .

Теперь мы можем применить их, выполнив следующую команду:

В отличие от команды makemigrations , при выполнении команды migrate вам никогда не нужно указывать приложение для миграции.

Примените вновь созданные миграции, запустив make migrate .

Наш первый пользователь

Мы создали нашу модель User , и наша база данных запущена и работает. Следующее, что нужно сделать, это создать наш первый объект User .Мы сделаем этого пользователя суперпользователем, поскольку мы будем использовать его для тестирования нашего сайта.

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

  python manage.py создает суперпользователя
  

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

Создайте своего первого пользователя, запустив python manage.py createduperuser .

Чтобы проверить, что пользователь был создан, давайте начнем с открытия оболочки Django из командной строки:

  управление питоном.py shell_plus
  

Если вы раньше использовали Django, возможно, вы знакомы с командой shell , но не с командой shell_plus . shell_plus предоставляется библиотекой django-extensions , которая была включена в шаблонный проект, который вы клонировали перед началом этого курса. Это полезно, потому что он автоматически импортирует модели для каждого приложения в настройке INSTALLED_APPS . Его также можно настроить для автоматического импорта других утилит.

После открытия оболочки запустите следующее:

ПРИМЕЧАНИЕ: Вводите только то, что появляется в строках, которым предшествуют >>> . Строки, которым не предшествуют >>> , выводятся из предыдущей команды.

  >>> user = User.objects.first ()
>>> user.username
'Джеймс'
>>> user.token
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE0Njk0MDY2OTksImlkIjoxfQ.qSnwWVD4PJKhKxgLxY0H5mkTE51QnMWv_kqN'
  

Если все прошло успешно, вы должны увидеть результат, аналогичный приведенному выше.

Регистрация новых пользователей

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

RegistrationSerializer

Создайте канал pipe / apps / authentication / serializers.py .

Начните с создания pipeit / apps / authentication / serializers.py и введите следующий код:

  из сериализаторов импорта rest_framework

из .models import User


класс RegistrationSerializer (сериализаторы.ModelSerializer):
    "" "Запрос на регистрацию сериализатора и создание нового пользователя." ""

    # Убедитесь, что пароли содержат не менее 8 символов, но не более 128
    # символов, и клиент не может их прочитать.
    пароль = сериализаторы.CharField (
        max_length = 128,
        min_length = 8,
        write_only = Верно
    )

    # Клиент не должен иметь возможность отправлять токен вместе с регистрацией
    # запрос. Сделав токен доступным только для чтения, мы справимся с этим.
    token = serializers.CharField (max_length = 255, read_only = True)

    класс Meta:
        model = Пользователь
        # Перечислить все поля, которые могут быть включены в запрос
        # или ответ, включая поля, явно указанные выше.fields = ['электронная почта', 'имя пользователя', 'пароль', 'токен']

    def create (self, validated_data):
        # Используйте метод create_user, который мы написали ранее, чтобы создать нового пользователя.
        вернуть User.objects.create_user (** validated_data)
  

Прочтите код, обращая особое внимание на комментарии, а затем продолжайте, когда закончите.

В приведенном выше коде мы создали класс RegistrationSerializer , который наследуется от сериализаторов .МодельSerializer . Сериализаторы .ModelSerializer - это просто абстракция поверх сериализаторов . Сериализатор , который вы, вероятно, помните из учебника Django REST Framework (DRF). ModelSerializer обрабатывает несколько вещей, относящихся к сериализации моделей Django, поэтому нам не нужно.

Также следует отметить, что он позволяет указать два метода: создать и обновить . В приведенном выше примере мы написали наш собственный метод create с использованием User.objects.create_user , но мы не указали метод update . В этом случае DRF будет использовать собственный метод обновления по умолчанию для обновления пользователя.

РегистрацияAPIView

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

Создайте канал / apps / authentication / views.py и введите следующее:

  из статуса импорта rest_framework
из rest_framework.разрешения импорт AllowAny
from rest_framework.response import Response
из rest_framework.views импортировать APIView

из .serializers импортировать RegistrationSerializer


класс RegistrationAPIView (APIView):
    # Разрешить любому пользователю (аутентифицированному или нет) подключаться к этой конечной точке.
    permission_classes = (AllowAny,)
    serializer_class = RegistrationSerializer

    def post (self, request):
        user = request.data.get ('пользователь', {})

        # Создание сериализатора, проверка сериализатора, сохранение шаблона сериализатора
        # ниже является распространенным, и вы будете часто его видеть на протяжении всего курса и
        # ваша собственная работа позже.Ознакомьтесь с этим.
        сериализатор = self.serializer_class (данные = пользователь)
        serializer.is_valid (raise_exception = True)
        serializer.save ()

        возврат ответа (serializer.data, status = status.HTTP_201_CREATED)
  

Давайте поговорим о паре новых вещей в этом фрагменте:

  1. Свойство permission_classes определяет, как мы решаем, кто может использовать эту конечную точку. Мы можем ограничить это авторизованными пользователями или администраторами. Мы также можем разрешить пользователям, которые аутентифицированы или нет, в зависимости от того, является ли эта конечная точка, к которой они обращаются, «безопасной» — это означает, что конечная точка представляет собой запрос GET , HEAD или OPTIONS .Для этого курса вам нужно знать только о запросах GET . Позже мы поговорим о permissions_classes .
  2. Создание сериализатора, проверка сериализатора, сохранение шаблона сериализатора, которые вы видите внутри метода post , очень распространены при использовании DRF. Вы захотите ознакомиться с этим шаблоном, поскольку вы будете его часто использовать.

Создайте канал / apps / authentication / views.py .

Теперь нам нужно настроить маршрутизацию для нашего проекта.Были внесены некоторые изменения в Django 1.x => 2.x при переключении с url на path . Есть довольно много вопросов по адаптации старого URL-адреса регулярного выражения к новому способу работы в пути. Компания «Внимательный код» создала URL-адрес для «Шпаргалки по путям» и написала об изменении. Некоторые уникальные обстоятельства могут потребовать использования re_path и регулярных выражений.

Создайте канал pipeline / authentication / urls.py и поместите в файл следующую строку для обработки наших маршрутов для этого приложения:

  из django.путь импорта URL

из .views import RegistrationAPIView

app_name = 'аутентификация'
urlpatterns = [
    путь ('пользователи /', RegistrationAPIView.as_view ()),
]
  

Если вы работаете с другим фреймворком, например, с Rails, обычно все маршруты помещаются в один файл. Хотя вы можете сделать это в Django, рекомендуется создавать пути для конкретных модульных приложений. Это заставляет задуматься о дизайне приложения и сохранении его автономности и возможности повторного использования. Вот что мы здесь сделали.Мы также указали app_name = 'authentication' , чтобы мы могли использовать include и сохранить наше приложение модульным. Теперь давайте включим указанный выше файл в наш файл глобальных URL-адресов.

Создайте канал / apps / authentication / urls.py .

Откройте файл pipeline / urls.py , и вы увидите следующую строку в верхней части файла:

  из пути импорта django.urls
  

Первое, что мы хотим сделать, это импортировать метод под названием include из django.URL-адреса :

  - из пути импорта django.urls
+ из django.urls import include, path
  

Метод include позволяет включить еще один файл urls.py без необходимости выполнять кучу работы, например, импортировать, а затем повторно регистрировать маршруты в этом файле.

Далее вы увидите следующее:

  urlpatterns = [
    путь ('admin /', admin.site.urls),
]
  

Давайте обновим это, чтобы включить наши новые URL-адресов.py файл:

  urlpatterns = [
    путь ('admin /', admin.site.urls),
+ путь ('api /', include ('pipeline.apps.authentication.urls', namespace = 'authentication')),
]
  

Включите URL-адреса из приложения для проверки подлинности в основной файл urls.py .

Регистрация пользователя в Postman

Теперь, когда мы создали модель User и добавили конечную точку для регистрации новых пользователей, мы собираемся выполнить быструю проверку работоспособности, чтобы убедиться, что мы на правильном пути.Для этого мы собираемся использовать инструмент под названием Postman с заранее созданным набором конечных точек.

Если вы никогда раньше не использовали Postman, ознакомьтесь с нашим руководством по тестированию приложений Conduit с использованием Postman.

Откройте Postman и используйте запрос «Регистрация» в папке «Auth» для создания нового пользователя.

Сделайте свой первый запрос почтальона.

Отлично! Сейчас мы добиваемся реального прогресса!

Но есть кое-что, что нам нужно исправить. Обратите внимание, как в ответе на запрос «Регистрация» содержится вся информация о пользователе на корневом уровне.Наш клиент ожидает, что эта информация будет помещена в пространство имен в разделе «пользователь». Для этого нам нужно создать настраиваемое средство визуализации DRF.

Визуализация пользовательских объектов

Создайте файл с именем pipeline / apps / authentication / renderers.py и введите следующее содержимое:

  импорт json

из rest_framework.renderers импортировать JSONRenderer


класс UserJSONRenderer (JSONRenderer):
    charset = 'utf-8'

    def render (self, data, media_type = None, renderer_context = None):
        # Если мы получим ключ `token` как часть ответа, это будет
        # байтовый объект.Байтовые объекты плохо сериализуются, поэтому нам нужно
        # декодировать его перед рендерингом объекта User.
        token = data.get ('токен', Нет)

        если токен не равен None, а isinstance (токен, байты):
            # Также, как упоминалось выше, мы будем декодировать токен, если он имеет тип
            # байт.
            данные ['токен'] = токен.decode ('utf-8')

        # Наконец, мы можем отображать наши данные в пространстве имён "user".
        return json.dumps ({
            'данные пользователя
        })

  

Создайте канал / apps / authentication / renderers.py .

Здесь ничего нового или интересного не происходит, поэтому просто прочтите комментарии во фрагменте, и мы можем двигаться дальше.

Теперь откройте pipeline / apps / authentication / views.py и импортируйте UserJSONRenderer , добавив следующую строку в начало файла:

  из .renderers импортировать UserJSONRenderer
  

Вам также необходимо установить свойство renderer_classes класса RegistrationAPIView следующим образом:

  класс RegistrationAPIView (APIView):
    permission_classes = (AllowAny,)
+ renderer_classes = (UserJSONRenderer,)
    serializer_class = RegistrationSerializer

    # … Другие вещи
  

Обновите RegistrationAPIView , чтобы использовать класс средства визуализации UserJSONRenderer .

Установив UserJSONRenderer , воспользуйтесь запросом почтальона «Регистрация» для создания нового пользователя. Обратите внимание, как на этот раз ответ находится внутри пространства имен «пользователь».

Зарегистрируйте нового пользователя в Postman.

Вход в систему

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

LoginSerializer

Откройте файл pipeline / apps / authentication / serializers.py и добавьте следующий импорт в начало файла:

  из django.contrib.auth импорт аутентификации
  

После этого создайте в том же файле следующий сериализатор:

  класс LoginSerializer (сериализаторы.Serializer):
    email = serializers.CharField (max_length = 255)
    username = serializers.CharField (max_length = 255, read_only = True)
    пароль = сериализаторы.CharField (max_length = 128, write_only = True)
    token = serializers.CharField (max_length = 255, read_only = True)

    def validate (self, data):
        # Метод `validate` - это то место, где мы убеждаемся, что текущий
        # экземпляр `LoginSerializer` имеет" действительный ". В случае регистрации
        # пользователь в, это означает подтверждение того, что они предоставили адрес электронной почты
        # и пароль и что эта комбинация соответствует одному из пользователей в
        # наша база данных.
        email = data.get ('электронная почта', Нет)
        пароль = данные.get ('пароль', Нет)

        # Вызвать исключение, если
        # адрес электронной почты не указан.
        если адрес электронной почты отсутствует:
            поднять сериализаторы.ValidationError (
                "Для входа требуется адрес электронной почты".
            )

        # Вызвать исключение, если
        # пароль не указан.
        если пароль None:
            поднять сериализаторы.ValidationError (
                «Для входа в систему требуется пароль».
            )

        # Метод аутентификации предоставляется Django и выполняет проверку
        # для пользователя, который соответствует этой комбинации адреса электронной почты и пароля.Обратите внимание, как
        # мы передаем `email` как значение` username`, поскольку в нашем User
        # model мы устанавливаем USERNAME_FIELD как email.
        пользователь = аутентификация (имя пользователя = адрес электронной почты, пароль = пароль)

        # Если не было найдено ни одного пользователя, соответствующего этой комбинации адреса электронной почты и пароля, тогда
        # `Authenticate` вернет` None`. В этом случае вызовите исключение.
        если пользователь None:
            поднять сериализаторы.ValidationError (
                «Пользователь с этим адресом электронной почты и паролем не найден».
            )

        # Django предоставляет флаг для нашей модели User, называемый is_active.В
        # цель этого флага - сообщить нам, был ли пользователь забанен
        # или деактивировано. Такого почти никогда не будет, но
        # стоит проверить. В этом случае вызовите исключение.
        если не user.is_active:
            поднять сериализаторы.ValidationError (
                "Этот пользователь был деактивирован".
            )

        # Метод `validate` должен возвращать словарь проверенных данных.
        # Это данные, которые передаются в методы `create` и` update`
        # что мы увидим позже.возвращение {
            "электронная почта": user.email,
            'username': user.username,
            'токен': user.token
        }
  

Добавьте новый класс LoginSerializer в файл pipeline / apps / authentication / serializers.py .

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

LoginAPIView

Откройте канал pipe / apps / authentication / views.py и обновите следующий импорт:

  -с.сериализаторы импортируют RegistrationSerializer
+ из импорта .serializers (
+ LoginSerializer, RegistrationSerializer
+)
  

Затем добавьте новое представление входа в систему:

  класс LoginAPIView (APIView):
    permission_classes = (AllowAny,)
    renderer_classes = (UserJSONRenderer,)
    serializer_class = LoginSerializer

    def post (self, request):
        user = request.data.get ('пользователь', {})

        # Обратите внимание, что мы не вызываем `serializer.save ()`, как это было для
        # конечная точка регистрации.Это потому, что у нас нет
        # все, что нужно сохранить. Вместо этого метод validate в нашем сериализаторе
        # обрабатывает все, что нам нужно.
        сериализатор = self.serializer_class (данные = пользователь)
        serializer.is_valid (raise_exception = True)

        возврат ответа (serializer.data, status = status.HTTP_200_OK)
  

Добавьте новый класс LoginAPIView в канал pipeline / apps / authentication / views.py .

Откройте канал pipe / apps / authentication / urls.py и обновите следующий импорт:

  -с.users / login /? $ ', LoginAPIView.as_view ()),
]
  

Добавьте шаблон URL-адреса для LoginAPIView в канал pipeline / apps / authentication / urls.py .

Вход пользователя в систему с помощью Postman

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

Войдите в систему, используя Postman.

Нам нужно еще кое-что сделать. Попробуйте использовать запрос «Вход», чтобы войти в систему с неверной комбинацией адреса электронной почты и пароля. Обратите внимание на ответ с ошибкой. С этим есть две проблемы.

Прежде всего

Учебное пособие: Регистрация и аутентификация пользователей Django

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

Регистрация пользователя Django через Google

Далее мы поговорим о самой последней версии Django: 1.11. Правильный инструмент для выполнения этой работы — python-social-auth.У него обширная документация, однако процесс чтения не очень очевиден. Итак, давайте посмотрим, как получить рабочую конфигурацию с минимальными усилиями.

Настройка python-social-auth

Прежде всего добавьте библиотеку в файл требований к pip и установите ее в виртуальную среду проекта. Имя пакета: social-auth-app-django. Вам нужно будет добавить следующие записи конфигурации в конфигурацию django (обычно settings.py):

  INSTALLED_APPS = [
    #...
    'social_django',
    # ...
]

AUTHENTICATION_BACKENDS = [
    'social_core.backends.google.GoogleOpenId',
    'social_core.backends.google.GoogleOAuth3',
]

SOCIAL_AUTH_GOOGLE_OAUTh3_KEY = "% some_digits_and_letters% .apps.googleusercontent.com"

SOCIAL_AUTH_GOOGLE_OAUTh3_SECRET = '% another_digits_and_letters%'  

Не обращайте внимания на последние две записи, пока они фиктивные. В следующем разделе мы увидим, как их правильно настроить.

Последний шаг минимальной настройки — это корневой urls.py:

  urlpatterns = [
url ('', include ('social_django.

Добавить комментарий

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