Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Miron-Anosov/60f4850f52099d8d25a6eb2a035e9fb3 to your computer and use it in GitHub Desktop.
Save Miron-Anosov/60f4850f52099d8d25a6eb2a035e9fb3 to your computer and use it in GitHub Desktop.

Руководство по аутентификации в Django

Содержание

Введение

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

Базовая настройка аутентификации

Для начала необходимо убедиться, что в settings.py добавлены необходимые middleware и приложения:

INSTALLED_APPS = [
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    ...
]

MIDDLEWARE = [
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    ...
]

Улучшенное шифрование с Argon2

Argon2 является рекомендованным алгоритмом хеширования паролей. Для его использования в Django:

  1. Установите необходимый пакет:
pip install django[argon2]
  1. Добавьте настройки в settings.py:
PASSWORD_HASHERS = [
    'django.contrib.auth.hashers.Argon2PasswordHasher',
    'django.contrib.auth.hashers.PBKDF2PasswordHasher',
    'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
]

Реализация представлений

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

# Представление для регистрации новых пользователей
class RegistrationView(CreateView):
    form_class = UserCreationForm
    template_name = "myauth/registration.html"
    success_url = reverse_lazy('myauth:me')
    
    def form_valid(self, form):
        # После успешной валидации формы создаем пользователя
        response = super().form_valid(form)
        username = form.cleaned_data.get('username')
        password = form.cleaned_data.get('password1')
        # Аутентифицируем и выполняем вход
        user = authenticate(self.request, username=username, password=password)
        login(self.request, user)
        LOGGER.info("User: %s was authenticated successfully", username)
        return response

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

# Представление для входа в систему
class LoginView(View):
    template_name = 'auth/login.html'
    
    def get(self, request: HttpRequest) -> HttpResponse:
        # Проверяем, не авторизован ли уже пользователь
        if request.user.is_authenticated:
            LOGGER.info("User %s already logged in", request.user)
            return redirect("auth:index")
            
        return render(request, self.template_name)
    
    def post(self, request: HttpRequest) -> HttpResponse:
        username = request.POST["username"]
        password = request.POST["pwd"]
        user = authenticate(request, username=username, password=password)
        
        if user is not None:
            login(request, user)
            LOGGER.info("User %s successfully logged in", user)
            return redirect("auth:index")
            
        LOGGER.warning("Failed login attempt for username: %s", username)
        return render(
            request,
            self.template_name,
            {'error': 'Invalid username or password'}
        )

Выход из системы

# Функциональное представление для выхода
def logout_view(request: HttpRequest) -> HttpResponse:
    logout(request)
    return redirect(reverse("auth:login"))

# Классовое представление для выхода
class LogOutView(View):
    def get(self, request):
        logout(request)
        return redirect('myauth:login')

Работа с cookies и сессиями

Управление cookies

# Установка cookie
def set_cookie_view(request: HttpRequest) -> HttpResponse:
    response = HttpResponse("Cookie set")
    response.set_cookie("fizz", "buzz", max_age=36000)
    return response

# Получение cookie
def get_cookie_view(request: HttpRequest) -> HttpResponse:
    value = request.COOKIES.get("fizz")
    return HttpResponse("Cookie value {}".format(value))

Управление сессиями

# Установка значения в сессию
def set_session_view(request: HttpRequest) -> HttpResponse:
    request.session["foobar"] = "spameggs"
    LOGGER.info("session: %s" % request.session.items())
    return HttpResponse("Session set")

# Получение значения из сессии
def get_session_view(request: HttpRequest) -> HttpResponse:
    val = request.session.get("foobar")
    return HttpResponse("Session value {}".format(val))

Безопасность

Рекомендации по безопасности:

  1. Всегда используйте HTTPS в продакшене
  2. Настройте правильные заголовки безопасности
  3. Используйте надёжные пароли
  4. Регулярно обновляйте Django до последней версии
  5. Используйте защиту от CSRF (встроена в Django)

Шаблоны

Для работы представлений необходимо создать соответствующие шаблоны:

  • myauth/registration.html - форма регистрации
  • myauth/login.html - форма входа
  • myauth/about-me.html - страница профиля пользователя

HTTPS конфигурация

В файле settings.py добавьте следующие настройки для обеспечения HTTPS:

# Перенаправление всех HTTP запросов на HTTPS
SECURE_SSL_REDIRECT = True

# Использовать безопасные куки только через HTTPS
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True

# Настройка HSTS (HTTP Strict Transport Security)
SECURE_HSTS_SECONDS = 31536000  # 1 год
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True

Заголовки безопасности

Добавьте следующие настройки в settings.py для установки важных заголовков безопасности:

# Защита от clickjacking атак
X_FRAME_OPTIONS = 'DENY'

# Включение XSS-фильтра браузера
SECURE_BROWSER_XSS_FILTER = True

# Предотвращение MIME-type сниффинга
SECURE_CONTENT_TYPE_NOSNIFF = True

# Настройка CSP (Content Security Policy)
CSP_DEFAULT_SRC = ("'self'",)
CSP_STYLE_SRC = ("'self'", "'unsafe-inline'")
CSP_SCRIPT_SRC = ("'self'",)
CSP_IMG_SRC = ("'self'",)
CSP_FONT_SRC = ("'self'",)

Для использования CSP необходимо установить django-csp:

pip install django-csp

И добавить middleware в settings.py:

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'csp.middleware.CSPMiddleware',
    # ... другие middleware
]

Дополнительные настройки безопасности

# Настройка длины паролей
AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
        'OPTIONS': {
            'min_length': 12,
        }
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
]

# Настройка сессий
SESSION_COOKIE_AGE = 1800  # 30 минут
SESSION_EXPIRE_AT_BROWSER_CLOSE = True

Рекомендации по развертыванию

  1. Используйте доверенный SSL/TLS сертификат (например, Let's Encrypt)
  2. Регулярно обновляйте все зависимости проекта
  3. Настройте правильные права доступа к файлам на сервере
  4. Используйте отдельные настройки для разработки и продакшена
  5. Регулярно проводите аудит безопасности

Пример конфигурации для продакшена в отдельном файле settings_prod.py:

from .settings import *

DEBUG = False
ALLOWED_HOSTS = ['your-domain.com']

# Настройки базы данных
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'your_db_name',
        'USER': 'your_db_user',
        'PASSWORD': 'your_db_password',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}

# Настройки кэширования
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.redis.RedisCache',
        'LOCATION': 'redis://127.0.0.1:6379/1',
    }
}

# Настройки логирования
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'file': {
            'level': 'WARNING',
            'class': 'logging.FileHandler',
            'filename': '/path/to/django/logs/prod.log',
        },
    },
    'loggers': {
        'django': {
            'handlers': ['file'],
            'level': 'WARNING',
            'propagate': True,
        },
    },
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment