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

Что такое basic авторизация?

1.8 Middle🔥 111 комментариев
#Python Core

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

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

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

HTTP Basic Authorization (Basic Auth)

Определение

Basic Authorization — это самый простой способ аутентификации в HTTP. Клиент отправляет username и password в header, закодированные в Base64.

Это НЕ шифрование, а просто кодирование для удобства передачи по HTTP.

Как работает Basic Auth

Шаг 1: Подготовка credentials

import base64

username = "user@example.com"
password = "mySecretPassword"

# Объединяем username:password
credentials = f"{username}:{password}"

# Кодируем в Base64
encoded = base64.b64encode(credentials.encode()).decode()
print(encoded)  # "dXNlckBleGFtcGxlLmNvbTpteVNlY3JldFBhc3N3b3Jk"

Шаг 2: Отправка в заголовке

import requests

username = "user@example.com"
password = "mySecretPassword"

# Способ 1: Вручную с заголовком Authorization
headers = {
    "Authorization": f"Basic {encoded}"
}
response = requests.get("https://api.example.com/data", headers=headers)

# Способ 2: Встроенный в requests (более удобно)
response = requests.get(
    "https://api.example.com/data",
    auth=(username, password)  # requests автоматически кодирует
)

print(response.status_code)

Шаг 3: Сервер проверяет credentials

from fastapi import FastAPI, HTTPException, Header
import base64
from typing import Annotated

app = FastAPI()

@app.get("/secure-data")
async def get_secure_data(
    authorization: Annotated[str | None, Header()] = None
):
    """Endpoint, защищённый Basic Auth"""
    
    if not authorization or not authorization.startswith("Basic "):
        raise HTTPException(status_code=401, detail="Missing authorization")
    
    # Извлекаем закодированную часть
    encoded = authorization.split(" ")[1]
    
    try:
        # Декодируем Base64
        decoded = base64.b64decode(encoded).decode()
        username, password = decoded.split(":")
    except (ValueError, IndexError):
        raise HTTPException(status_code=400, detail="Invalid authorization format")
    
    # Проверяем credentials
    if username != "admin" or password != "secret123":
        raise HTTPException(status_code=401, detail="Invalid credentials")
    
    return {"data": "This is secure data", "user": username}

Более безопасный способ: хеширование паролей

from fastapi import Depends, HTTPException
from fastapi.security import HTTPBasic, HTTPBasicCredentials
import hashlib

security = HTTPBasic()

# БД с хешированными паролями (в реальности это БД)
USERS = {
    "admin": "8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918"  # bcrypt хеш от "admin"
}

def verify_password(password: str, hashed: str) -> bool:
    """Проверяет пароль против хеша"""
    return hashlib.sha256(password.encode()).hexdigest() == hashed

@app.get("/admin-only")
async def admin_only(credentials: HTTPBasicCredentials = Depends(security)):
    """Эндпойнт с Basic Auth через FastAPI встроенный механизм"""
    
    if credentials.username not in USERS:
        raise HTTPException(status_code=401, detail="Invalid user")
    
    # Проверяем пароль
    if not verify_password(credentials.password, USERS[credentials.username]):
        raise HTTPException(status_code=401, detail="Invalid password")
    
    return {"message": f"Welcome {credentials.username}!"}

Декодирование Basic Auth

import base64

# Декодирование
encoded = "dXNlckBleGFtcGxlLmNvbTpteVNlY3JldFBhc3N3b3Jk"
decoded = base64.b64decode(encoded).decode()
username, password = decoded.split(":")
print(f"Username: {username}")
print(f"Password: {password}")

Структура HTTP запроса с Basic Auth

GET /api/data HTTP/1.1
Host: api.example.com
Authorization: Basic dXNlckBleGFtcGxlLmNvbTpteVNlY3JldFBhc3N3b3Jk
User-Agent: Python-Requests/2.28.0


Проблемы и ограничения Basic Auth

1. НЕ безопасно без HTTPS

# ❌ ОПАСНО: Basic Auth по HTTP
response = requests.get(
    "http://api.example.com/data",  # Незащищённый HTTP!
    auth=("admin", "password123")
)
# ^ Пароль передаётся в открытом виде (хотя и закодирован в Base64)

# ✅ ТОЛЬКО по HTTPS
response = requests.get(
    "https://api.example.com/data",  # Защищённый HTTPS
    auth=("admin", "password123")
)

Почему: Base64 это кодирование, не шифрование. Его легко декодировать.

2. Нет логаута

# Basic Auth включена — отключить её невозможно
# Браузер запомнит credentials и будет отправлять их автоматически
# Единственный способ "выйти" — закрыть браузер или очистить кеш

3. Нет истечения токена

# Credentials не истекают автоматически
# Если украдены, используются вечно (пока не изменен пароль)

4. Нельзя использовать на фронтенде

// ❌ Плохо: пароль в JavaScript
const credentials = 'admin:password123';
const encoded = btoa(credentials);
fetch('/api/data', {
    headers: {
        'Authorization': `Basic ${encoded}`
    }
});
// ^ Пароль видна в исходном коде и в DevTools Network

Когда использовать Basic Auth

Хорошо для:

  • API между сервисами (server-to-server)
  • Внутренние инструменты
  • Временный доступ
  • Быстрое прототипирование
  • IoT устройства и встроенные системы

Плохо для:

  • Публичные веб-приложения
  • Мобильные приложения
  • Фронтенд (JavaScript)
  • Sensitive данные

Альтернативы Basic Auth

# 1. OAuth 2.0 (для публичных API)
# Пример: авторизация через Google, GitHub

# 2. JWT токены
from fastapi import Depends
from fastapi.security import HTTPBearer, HTTPAuthenticationCredentials

security = HTTPBearer()

@app.get("/data")
async def get_data(credentials: HTTPAuthenticationCredentials = Depends(security)):
    token = credentials.credentials  # JWT токен
    # Проверяем и декодируем token
    pass

# 3. API Keys
@app.get("/data")
async def get_data(api_key: str = Header(None)):
    if api_key != "sk-1234567890":
        raise HTTPException(status_code=401)
    return {"data": "secure"}

# 4. Digest Auth (с хешем вместо Base64)
# Более безопаснее Basic, но старомодно

Реальный пример: защита внутреннего API

from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import HTTPBasic, HTTPBasicCredentials
import secrets

app = FastAPI()
security = HTTPBasic()

# Credentials для внутреннего API
VALID_USERS = {
    "service-1": "very-secret-password-123",
    "service-2": "another-secret-456"
}

async def verify_credentials(credentials: HTTPBasicCredentials = Depends(security)):
    """Проверяет Basic Auth credentials"""
    
    # Используем secrets.compare_digest для защиты от timing attack
    correct_username = False
    correct_password = False
    
    if credentials.username in VALID_USERS:
        correct_password = secrets.compare_digest(
            credentials.password,
            VALID_USERS[credentials.username]
        )
        correct_username = True
    
    if not (correct_username and correct_password):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid credentials",
            headers={"WWW-Authenticate": "Basic"}
        )
    
    return credentials.username

@app.get("/internal/metrics")
async def get_metrics(username: str = Depends(verify_credentials)):
    return {"metrics": "data", "accessed_by": username}

Итог

Basic Authorization — это:

  • Самый простой метод аутентификации
  • ТОЛЬКО для HTTPS
  • Хорошо для server-to-server коммуникации
  • Плохо для фронтенда и публичных API
  • Должна использоваться с хешированием паролей на сервере
  • Основана на Base64 кодировании (не шифровании!)

Для производства рекомендуется использовать OAuth 2.0 или JWT вместо Basic Auth.

Что такое basic авторизация? | PrepBro