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

Что такое аутентификация?

2.0 Middle🔥 301 комментариев
#Тестирование

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

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

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

Аутентификация (Authentication)

Аутентификация — это процесс проверки подлинности пользователя. Система убеждается, что пользователь действительно тот, за кого себя выдаёт. Ответ на вопрос: "Ты кто?"

Аутентификация vs Авторизация

Эти два термина часто путают:

  • Аутентификация — кто ты? (Identity: "я Alice")
  • Авторизация — что ты можешь делать? (Permissions: "Alice может редактировать посты")
# Пример: проверка доступа
1. Аутентификация → login("alice", "password123") → Хорошо! Ты Alice
2. Авторизация → can_edit_post(alice, post_id) → Да, Alice может редактировать

Методы аутентификации

1. Basic Authentication (логин + пароль)

# Самый простой метод
from fastapi import FastAPI, HTTPException, Depends
from fastapi.security import HTTPBasic, HTTPBasicCredentials
import hashlib

app = FastAPI()
security = HTTPBasic()

# База пользователей (в реальной жизни — БД)
USERS = {
    "alice": "hashed_password_123",
    "bob": "hashed_password_456"
}

def hash_password(password: str) -> str:
    """Хэширование пароля (используй bcrypt в продакшене!)"""
    return hashlib.sha256(password.encode()).hexdigest()

@app.get("/protected")
def protected_route(credentials: HTTPBasicCredentials = Depends(security)):
    """Защищённый эндпойнт"""
    # Проверяем пользователя
    hashed = hash_password(credentials.password)
    if credentials.username not in USERS or USERS[credentials.username] != hashed:
        raise HTTPException(status_code=401, detail="Invalid credentials")
    
    return {"message": f"Hello, {credentials.username}!"}

2. Token-Based Authentication (JWT)

from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import HTTPBearer, HTTPAuthCredentials
from datetime import datetime, timedelta, UTC
import jwt

app = FastAPI()
security = HTTPBearer()

SECRET_KEY = "your-secret-key"
ALGORITHM = "HS256"
TOKEN_EXPIRE = timedelta(hours=1)

def create_token(user_id: str) -> str:
    """Создание JWT токена"""
    payload = {
        "user_id": user_id,
        "exp": datetime.now(UTC) + TOKEN_EXPIRE,
        "iat": datetime.now(UTC)
    }
    return jwt.encode(payload, SECRET_KEY, algorithm=ALGORITHM)

@app.post("/login")
def login(username: str, password: str):
    """Вход — выдача токена"""
    # Проверка учётных данных
    if not verify_credentials(username, password):
        raise HTTPException(status_code=401, detail="Invalid credentials")
    
    token = create_token(username)
    return {"access_token": token, "token_type": "bearer"}

def verify_token(credentials: HTTPAuthCredentials = Depends(security)):
    """Проверка токена в защищённых эндпойнтах"""
    try:
        payload = jwt.decode(credentials.credentials, SECRET_KEY, algorithms=[ALGORITHM])
        user_id = payload.get("user_id")
        if not user_id:
            raise HTTPException(status_code=401, detail="Invalid token")
        return user_id
    except jwt.ExpiredSignatureError:
        raise HTTPException(status_code=401, detail="Token expired")
    except jwt.DecodeError:
        raise HTTPException(status_code=401, detail="Invalid token")

@app.get("/me")
def get_user(user_id: str = Depends(verify_token)):
    """Получить текущего пользователя"""
    return {"user_id": user_id, "message": "Your protected data"}

3. OAuth 2.0 (делегированная аутентификация)

# Вход через Google, GitHub, Facebook и т.д.
# Пользователь НЕ передаёт пароль вашему приложению

from fastapi import FastAPI
from authlib.integrations.starlette_client import OAuth

app = FastAPI()
oauth = OAuth()

oauth.register(
    name="google",
    client_id="YOUR_CLIENT_ID",
    client_secret="YOUR_CLIENT_SECRET",
    server_metadata_url="https://accounts.google.com/.well-known/openid-configuration",
    client_kwargs={"scope": "openid email profile"}
)

@app.get("/auth/login")
async def login(request):
    """Редирект на Google для аутентификации"""
    redirect_uri = request.url_for("auth")
    return await oauth.google.authorize_redirect(request, redirect_uri)

@app.get("/auth/callback")
async def auth(request):
    """Callback после успешной аутентификации в Google"""
    token = await oauth.google.authorize_access_token(request)
    user_info = token["userinfo"]
    return {"user": user_info}

4. Multi-Factor Authentication (MFA)

# Двухфакторная аутентификация: пароль + код из SMS/приложения

def authenticate_with_mfa(username: str, password: str, totp_code: str):
    """Аутентификация с двумя факторами"""
    # Шаг 1: Проверка пароля
    if not verify_password(username, password):
        raise Exception("Invalid password")
    
    # Шаг 2: Проверка TOTP кода (Time-based One-Time Password)
    user = get_user(username)
    if not verify_totp(user.totp_secret, totp_code):
        raise Exception("Invalid TOTP code")
    
    # Оба фактора верны — аутентификация успешна
    return create_token(username)

Процесс аутентификации: пошагово

1. Пользователь вводит логин и пароль
   ↓
2. Приложение отправляет на сервер
   ↓
3. Сервер проверяет учётные данные в БД
   ↓
4. Пароль совпадает → выдаёт токен/сессию
   ↓
5. Клиент сохраняет токен
   ↓
6. При каждом запросе отправляет токен в заголовке Authorization
   ↓
7. Сервер проверяет токен → разрешает доступ

Безопасность паролей

# ❌ Неправильно — хранить пароль в открытом виде
USERS = {"alice": "password123"}

# ✅ Правильно — использовать хеширование
from bcrypt import hashpw, gensalt, checkpw

hashed = hashpw("password123".encode(), gensalt())
# $2b$12$abcdef...

# Проверка при входе
if checkpw("password123".encode(), hashed):
    print("Password correct!")

Сессии vs Токены

ПараметрСессияТокен (JWT)
Где хранитьНа сервереНа клиенте
МасштабируемостьСложно (нужна синхронизация)Легко (stateless)
Память сервераТребуетсяНе требуется
СкоростьМедленнее (поиск в БД)Быстрее (валидация подписи)
ОтзывНемедленныйТолько до истечения срока

Ключевые моменты

  • Аутентификация = проверка подлинности (кто ты?)
  • Пароли ВСЕГДА хешируются (bcrypt, argon2)
  • JWT токены — stateless и масштабируемы
  • Refresh Token — для обновления доступа
  • HTTPS обязателен — для передачи учётных данных
  • MFA — дополнительный уровень безопасности
  • OAuth 2.0 — безопасная делегированная аутентификация
Что такое аутентификация? | PrepBro