← Назад к вопросам

Что такое сессия во фреймворке?

1.8 Middle🔥 131 комментариев
#DevOps и инфраструктура#Django

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Сессия во фреймворке (Session)

Сессия — это объект, который сохраняет данные о текущем пользователе или клиенте на протяжении нескольких запросов HTTP. Это позволяет отслеживать состояние пользователя, как-то аутентификация, корзину покупок, параметры фильтра и другие данные, без необходимости передавать всё это каждый раз в запросе.

Без сессий каждый HTTP-запрос был бы независимым — сервер не знал бы, кто это. С сессиями сервер может узнать пользователя по ID или токену.

Как работает сессия

Пользователь                              Сервер
1. Логин (username, password) ────────> Проверка credentials
2.                                       Создание session_id
3.                                       Сохранение в памяти/БД
4. <────────────── Set-Cookie: session_id=abc123
5. Браузер сохраняет cookie
6. Запрос к /profile ──────────────────> session_id=abc123
7.                                       Поиск session_id → User(john)
8. <────────────── Данные профиля John

Сессия в Flask

from flask import Flask, session, request

app = Flask(__name__)
app.secret_key = 'your-secret-key-here'

@app.route('/login', methods=['POST'])
def login():
    username = request.form.get('username')
    password = request.form.get('password')
    
    # Проверка креденшалов
    if verify_user(username, password):
        session['user_id'] = user.id
        session['username'] = user.username
        session['role'] = user.role
        return "Logged in successfully"
    return "Invalid credentials", 401

@app.route('/profile')
def profile():
    user_id = session.get('user_id')
    
    if not user_id:
        return "Not logged in", 401
    
    user = get_user_by_id(user_id)
    return f"Welcome {user.username}"

@app.route('/logout')
def logout():
    session.clear()
    return "Logged out"

Сессия в Django

from django.shortcuts import render
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required

def login_view(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        
        user = authenticate(request, username=username, password=password)
        
        if user is not None:
            login(request, user)  # Создаёт сессию
            # session.session_key содержит ID сессии
            request.session['shopping_cart'] = []
            return redirect('/profile')
    return render(request, 'login.html')

@login_required
def profile(request):
    user = request.user
    shopping_cart = request.session.get('shopping_cart', [])
    return render(request, 'profile.html', {'user': user, 'cart': shopping_cart})

def logout_view(request):
    logout(request)  # Удаляет сессию
    return redirect('/')

Сессия в FastAPI

from fastapi import FastAPI, Request
from starlette.sessions import SessionMiddleware
from starlette.responses import JSONResponse

app = FastAPI()

# Добавляем middleware для работы с сессиями
app.add_middleware(SessionMiddleware, secret_key="your-secret-key")

@app.post("/login")
async def login(request: Request, username: str, password: str):
    # Проверка креденшалов
    if verify_user(username, password):
        user = get_user(username)
        request.session["user_id"] = user.id
        request.session["username"] = user.username
        return {"message": "Logged in"}
    return {"error": "Invalid credentials"}, 401

@app.get("/profile")
async def get_profile(request: Request):
    user_id = request.session.get("user_id")
    
    if not user_id:
        return {"error": "Not authenticated"}, 401
    
    user = get_user_by_id(user_id)
    return {"username": user.username, "email": user.email}

@app.post("/logout")
async def logout(request: Request):
    request.session.clear()
    return {"message": "Logged out"}

Сохранение данных в сессию

from flask import Flask, session
import json

app = Flask(__name__)
app.secret_key = 'secret'

@app.route('/add-to-cart/<int:product_id>')
def add_to_cart(product_id):
    cart = session.get('shopping_cart', [])
    cart.append({
        'product_id': product_id,
        'quantity': 1
    })
    session['shopping_cart'] = cart
    session.modified = True  # Обязательно для сложных типов
    return {"cart": session['shopping_cart']}

@app.route('/cart')
def view_cart():
    cart = session.get('shopping_cart', [])
    total = sum(item['quantity'] for item in cart)
    return {"items": len(cart), "total_quantity": total}

Время жизни сессии

from flask import Flask
from datetime import timedelta

app = Flask(__name__)

# Сессия живёт 30 минут
app.permanent_session_lifetime = timedelta(minutes=30)

@app.route('/login')
def login():
    session.permanent = True  # Сессия сохранится на диск
    session['user_id'] = 123
    return "Logged in"

Бэкенд сохранения сессий

В памяти (по умолчанию):

from flask import Flask

app = Flask(__name__)
app.secret_key = 'secret'
# Сессии хранятся в памяти — теряются при перезагрузке

В БД (Redis):

from flask import Flask
from flask_session import Session
import redis

app = Flask(__name__)
app.config['SESSION_TYPE'] = 'redis'
app.config['SESSION_REDIS'] = redis.from_url('redis://localhost:6379')

Session(app)
# Сессии хранятся в Redis — доступны всем экземплярам приложения

В БД (SQL):

from flask_sqlalchemy import SQLAlchemy
from flask import Flask

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://user:pass@localhost/db'
app.config['SESSION_TYPE'] = 'sqlalchemy'
db = SQLAlchemy(app)

# Сессии в PostgreSQL — надёжно и масштабируемо

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

from flask import Flask, session
from datetime import timedelta

app = Flask(__name__)
app.secret_key = 'very-strong-secret-key-256-bits'  # Длинный и сложный

# Параметры безопасности
app.config['SESSION_COOKIE_SECURE'] = True      # Только через HTTPS
app.config['SESSION_COOKIE_HTTPONLY'] = True    # JS не может получить cookie
app.config['SESSION_COOKIE_SAMESITE'] = 'Lax'   # CSRF защита
app.permanent_session_lifetime = timedelta(hours=1)  # Короткое время жизни

Проверка аутентификации

from flask import Flask, session, abort
from functools import wraps

app = Flask(__name__)

def login_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if 'user_id' not in session:
            abort(401)  # Unauthorized
        return f(*args, **kwargs)
    return decorated_function

@app.route('/admin')
@login_required
def admin_panel():
    user_id = session['user_id']
    return f"Admin panel for user {user_id}"

Сессия vs Токены (JWT)

АспектСессияJWT Токен
ХранениеНа сервереВ браузере (cookie/localStorage)
МасштабируемостьТребует shared storage (Redis)Нет состояния на сервере
ОтзывМгновенный (удалить из памяти)Сложный (нужен blacklist)
БезопасностьВысокая (хранится на сервере)Требует SSL/TLS
CSRFТребует CSRF токенБолее защищён

Лучшие практики

  • Используй HTTPS — сессия передаётся в cookie, легко перехватить
  • Генерируй стойкий secret_key — минимум 32 символа
  • Устанавливай время жизни — слишком долгие сессии — риск безопасности
  • Регулярно очищай старые сессии — не копи их
  • Логируй вход/выход — аудит безопасности
  • Используй SECURE + HTTPONLY флаги для cookies
  • Для микросервисов рассмотри JWT вместо сессий

Сессия — это основной механизм отслеживания состояния пользователя в веб-приложениях, обеспечивая безопасное и удобное взаимодействие.