← Назад к вопросам
Как получить токен на сервере?
1.0 Junior🔥 241 комментариев
#REST API и HTTP#Безопасность
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Как получить токен на сервере
Получение токена — это критический процесс аутентификации. Покажу основные методы.
Метод 1: Basic Authentication
Используешь логин и пароль в заголовке Authorization. Базовый метод, но небезопасен без HTTPS.
import base64
from flask import request, jsonify
@app.route('/api/token', methods=['POST'])
def get_token():
auth_header = request.headers.get('Authorization', '')
if not auth_header.startswith('Basic '):
return jsonify({'error': 'No Basic auth'}), 401
encoded = auth_header[6:]
decoded = base64.b64decode(encoded).decode('utf-8')
username, password = decoded.split(':', 1)
user = db.query(User).filter_by(username=username).first()
if not user or not verify_password(password, user.hashed_password):
return jsonify({'error': 'Invalid credentials'}), 401
token = create_jwt_token(user.id)
return jsonify({'access_token': token, 'token_type': 'Bearer'})
Метод 2: JSON с логином и паролем
Более удобен для фронтенда — передаёшь данные в JSON теле запроса.
@app.route('/api/login', methods=['POST'])
def login():
data = request.json
username = data.get('username')
password = data.get('password')
user = db.query(User).filter_by(username=username).first()
if not user or not verify_password(password, user.hashed_password):
return jsonify({'error': 'Invalid credentials'}), 401
access_token = create_jwt_token(user.id, expires_in=900)
refresh_token = create_jwt_token(user.id, expires_in=2592000)
return jsonify({
'access_token': access_token,
'refresh_token': refresh_token,
'token_type': 'Bearer',
'expires_in': 900,
})
Метод 3: OAuth 2.0
Для интеграций и третьих приложений.
import secrets
from datetime import datetime, timedelta
@app.route('/oauth/token', methods=['POST'])
def oauth_token():
grant_type = request.form.get('grant_type')
if grant_type == 'password':
username = request.form.get('username')
password = request.form.get('password')
user = db.query(User).filter_by(username=username).first()
if not user or not verify_password(password, user.hashed_password):
return jsonify({'error': 'invalid_credentials'}), 401
access_token = secrets.token_urlsafe(64)
return jsonify({
'access_token': access_token,
'token_type': 'Bearer',
'expires_in': 3600,
})
Метод 4: Service Account (сервер-к-серверу)
Для микросервисов и фоновых задач.
import jwt
from datetime import datetime, timedelta
class ServiceAccountManager:
def __init__(self, private_key: str, service_account_id: str):
self.private_key = private_key
self.service_account_id = service_account_id
def create_access_token(self, expires_in: int = 3600) -> str:
now = datetime.utcnow()
payload = {
'iss': self.service_account_id,
'aud': 'https://api.example.com',
'exp': now + timedelta(seconds=expires_in),
'iat': now,
}
return jwt.encode(payload, self.private_key, algorithm='RS256')
Метод 5: API Key
Для долгоживущих ключей, которые не истекают.
import secrets
@app.route('/api/generate-key', methods=['POST'])
def generate_api_key():
api_key = f"sk_{secrets.token_urlsafe(32)}"
db.add(APIKey(
key=hash_api_key(api_key),
user_id=current_user.id
))
db.commit()
return jsonify({
'api_key': api_key,
'message': 'Store this securely'
})
Общая функция создания JWT
from datetime import datetime, timedelta
import jwt
SECRET_KEY = 'your-secret-key'
ALGORITHM = 'HS256'
def create_jwt_token(user_id: int, expires_in: int = 3600) -> str:
now = datetime.utcnow()
payload = {
'user_id': user_id,
'exp': now + timedelta(seconds=expires_in),
'iat': now,
'type': 'access',
}
return jwt.encode(payload, SECRET_KEY, algorithm=ALGORITHM)
Безопасность
Обязательно делай:
- Используй HTTPS для всех запросов с токенами
- Хэшируй пароли с bcrypt или argon2
- Ограничивай попытки логина (rate limiting)
- Делай короткоживущие access токены (15 минут)
- Логируй все попытки получения токена
- Используй refresh токены для обновления
Никогда не делай:
- Не передавай пароли в GET параметрах
- Не сохраняй токены в cookies без httpOnly флага
- Не логируй полные токены
- Не встраивай секреты в код
Рекомендуемый подход
- Пользователь отправляет POST /api/login с username и password
- Сервер проверяет credentials
- Если верно — выдаёт два токена:
- Access token (15 мин, используется для API)
- Refresh token (30 дней, используется для получения нового access)
- Клиент хранит tokens в памяти или secure storage
- При запросе к API отправляет access token в Authorization заголовке
- Когда access token истёк — клиент использует refresh token для получения нового