Django permissions. Управление правами доступа

28 Май 2021 , 21782

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

После создания нового проекта на Django , то в файле settings.py вы можете увидеть , что система аутентификации django.contrib.auth уже включена . Также по умолчанию включена система типов контента Django django.contrib.contenttypes, которая позволяет связывать разрешения(permissons) с создаваемыми вами моделями.


'INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth', #Система аутентификации
    'django.contrib.contenttypes', # Cистема типов контента 
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]


С этими настройками после выполнения команды python manage.py migrate в базе данных создаются необходимые таблицы для моделей связанных с аутентификацией и с разрешениями(permissions)

Таким образом , Django имеет встроенную систему разрешений(permissions). Эта система позволяет назначать разрешения конкретным пользователям и группам пользователей.

Эту систему использует Django admin

Django по умолчанию для модели создает 4 разрешения. Давайте посмотрим это на примере и потом подробно обсудим все 4 разрешения предоставляемых для модели по умолчанию

Создадим в нашем проекте новое приложение(application)


python manage.py startapp blog

В файле models.py создадим модель Post


from django.db import models


class Post(models.Model):
    name = models.CharField(max_length=255)
    content = models.TextField()

    def __str__(self):
        return self.name


Создадим миграции

После выполнения миграции в базе данных создается таблица blog_post. Также в таблицу auth_permission добавляются четыре разрешения(permissions) ассоциированных с моделью Post.

Django permissions

Django для нашей модели Post после выполнения миграций создала четыре разрешения

  • Разрешение add(в нашем случае add_post) позволяет пользователям добавлять экземпляры модели.
  • Разрешение change(в нашем случае change_post) позволяет пользователям редактировать экземпляры модели
  • Разрешение delete(в нашем случае delete_post) позволяет пользователям удалять экземпляры модели
  • Разрешение view(в нашем случае view_post) позволяет пользователям просматривать экземпляры данной модели. Это разрешение появилось в Django 2.1

Имена разрешений следуют особому соглашению об именах: ._

В нашем случае для модели Post разрешения будут выглядеть следующим образом:

  • blog.add_post , где blog - это имя приложения(app), add - это действие(action), а post - это название модели(modelname)
  • blog.change_post , где blog - это имя приложения(app), change - это действие(action), а post - это название модели(modelname)
  • blog.delete_post , где blog - это имя приложения(app), delete - это действие(action), а post - это название модели(modelname)
  • blog.view_post , где blog - это имя приложения(app), view - это действие(action), а post - это название модели(modelname)

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

Django permissions

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

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

Разрешения пользователям мы можем задавать не только в административной панели Django, но также программно. Мы можем управлять разрешениями следующими методами:


myuser.user_permissions.set([permission_list])
myuser.user_permissions.add(permission, permission, ...)
myuser.user_permissions.remove(permission, permission, ...)
myuser.user_permissions.clear()

В приложении blog для модели Blog создадим вьюху для добавления поста. Добавлять пост может только пользователь у которого будет разрешение add_post


from django.contrib.auth.mixins import PermissionRequiredMixin


class CreatePostView(PermissionRequiredMixin, CreateView):
    permission_required = 'blog.add_post'
    model = Post
    fields = ('name', 'content')

Здесь мы используем миксин PermissionRequiredMixin , потому что мы используем CreateView для создания нового объекта модели поста. У миксина PermissionRequiredMixin в поле permission_required мы задаем разрещение : blog.add_post.Если пользователь аутентифицирован , но при этом у него нет разрешения добавлять посты , то ему будет отказано в доступе к этой вьюхе и будет возвращен код 403(Доступ воспрещен). А если у него будет разрещение blog.add_post , то он сможет создать новый пост

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


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

@login_required
@permission_required('blog.add_post', raise_exception=True)
def add_post(request):
    #Код для добавления нового поста
    return render(request)

Также мы можем проверять есть ли у данного пользователя определенное разрешение или нет , с помощью метода has_perm


def add_post(request):
    #Проверяем есть ли у данного пользователя разрешение для добавления поста 
    #Если такого разрешения нет, то выкидываем исключение PermissionDenied
    if not request.user.has_perm('blog.add_post'):
        raise PermissionDenied
    # Бизнес-логика для добавления поста


Для неаутентифицированного пользователя AnonymousUser метод has_perm всегда будет возвращать false.

Заключение

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

comments powered by Disqus

Подписка

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

Рубрики

Теги