← Назад к вопросам
Что такое сессия во фреймворке?
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 вместо сессий
Сессия — это основной механизм отслеживания состояния пользователя в веб-приложениях, обеспечивая безопасное и удобное взаимодействие.