Как в Python реализовать авторизацию, то есть проверку прав доступа?

Ответ

Авторизация — это процесс проверки, имеет ли аутентифицированный пользователь разрешение на выполнение определенного действия или доступ к ресурсу. Она следует за аутентификацией.

Ключевое различие:

  • Аутентификация: Кто вы? (Проверка личности)
  • Авторизация: Что вам можно делать? (Проверка прав)

Основные подходы к реализации авторизации:

  1. Управление доступом на основе ролей (Role-Based Access Control, RBAC) Это самый распространенный подход. Пользователям назначаются роли (например, admin, editor, viewer), а разрешения привязываются к ролям.

    Пример с помощью декоратора в Flask:

    from functools import wraps
    from flask import request, abort, g
    
    def requires_role(role):
        def decorator(f):
            @wraps(f)
            def decorated_function(*args, **kwargs):
                # Предполагается, что информация о пользователе и его роли
                # уже загружена после аутентификации и доступна в `g.user`
                if not g.user or g.user.role != role:
                    abort(403)  # Forbidden
                return f(*args, **kwargs)
            return decorated_function
        return decorator
    
    @app.route('/admin/dashboard')
    @login_required # Сначала аутентификация
    @requires_role('admin') # Затем авторизация
    def admin_dashboard():
        return "Welcome, Admin!"
  2. Управление доступом на основе атрибутов (Attribute-Based Access Control, ABAC) Более гибкий подход, где решение о доступе принимается на основе атрибутов пользователя, запрашиваемого ресурса и окружения (например, время суток, IP-адрес).

Готовые решения в фреймворках:

  • Django: Имеет мощную встроенную систему аутентификации и авторизации с пользователями, группами и разрешениями (permissions).
  • Flask: Используются расширения, например, Flask-Principal или Flask-Security-Too, для реализации сложных схем авторизации.
  • FastAPI: Авторизация часто реализуется с помощью зависимостей (dependencies), которые проверяют права доступа на основе данных из JWT-токена или другого источника.

Ответ 18+ 🔞

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

Короче, представь себе клуб. Ты подходишь к вышибале (это аутентификация). Он тебя смотрит, проверяет лицо, паспорт, может, даже биометрию какую-нибудь — ты это ты? Да? Отлично, ты прошёл. Но это ещё не всё, дружок!

Теперь второй этап: авторизация. Ты внутри клуба. И вот тут начинается: тебе можно только в общий зал пиво пить, а вот за VIP-вельветовую верёвочку — ни-ни. А твоему корешу, который владелец, можно и в подсобку, и за барную стойку, и в кабинет к директору. Вот эта вот хуйня — проверка, что тебе можно — и есть авторизация. Понял разницу? Аутентификация — ты ли это, авторизация — что тебе можно.

Теперь, как эту хуйню в коде делать. Самый популярный способ, который все юзают, — это RBAC (Role-Based Access Control), или, по-нашему, «раздача прав по ролям». Суть проще пареной репы: есть роли (admin, user, editor), и в зависимости от роли тебе доступны разные пизюльки.

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

from functools import wraps
from flask import request, abort, g

def requires_role(role):
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            # Допустим, после аутентификации мы запихнули данные юзера в `g.user`
            if not g.user or g.user.role != role:
                abort(403)  # Forbidden — пошёл нахуй, доступ закрыт
            return f(*args, **kwargs)
        return decorated_function
    return decorator

@app.route('/admin/dashboard')
@login_required # Сначала проверяем, а кто ты вообще такой? (аутентификация)
@requires_role('admin') # А теперь — а можно ли тебе? (авторизация)
def admin_dashboard():
    return "Welcome, Admin!"

Видишь? Сначала декоратор @login_required спрашивает: «Ты кто?». Потом @requires_role('admin') уточняет: «А ты точно админ? Не полупидор?». И если нет — получаешь ошибку 403, то есть, грубо говоря, «иди нахуй, не твоё».

Но это, конечно, примитив. Бывает, что нужно не просто по роли, а с кучей условий: время дня, IP-адрес, фаза луны, твой стаж на проекте. Это уже ABAC (Attribute-Based Access Control) — управление доступом на основе атрибутов. Гибко, мощно, но и мозг выносит конкретно. Это как если бы вышибала спрашивал не только твою роль, но и: «А ты сегодня носки поменял? А зарплату получил? А дождь на улице? Нет? Тогда иди нахуй».

Что касается готовых решений — фреймворки уже всё за тебя придумали, ленивая жопа:

  • Django: Там это всё из коробки, как шведский стол. Пользователи, группы, разрешения (permissions) — настраивай, не хочу. Очень удобно, если не боишься его монструозности.
  • Flask: Сам по себе он голый, но для него есть куча расширений. Хочешь мощную авторизацию — бери Flask-Principal или Flask-Security-Too. Сделают всё красиво, только разберись.
  • FastAPI: Там модно всё через зависимости (dependencies) делать. Получил JWT-токен, распарсил, посмотрел права внутри — и пустил или нет. Стильно, современно, быстро.

Вот и вся магия. Главное — не путай эти два понятия, а то получится как в том анекдоте: «Я знаю пароль, но я не знаю, куда его вводить». Сначала докажи, кто ты, а потом уже лезь куда не следует. Всё просто, ёпта!