sno-quiz/backend/AUTH_GUIDE.md
2025-09-17 22:22:14 +03:00

209 lines
6.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Telegram WebApp Authentication Guide
## 📋 Обзор
Система аутентификации использует Telegram WebApp initData для безопасной верификации пользователей.
## 🔧 Как это работает
1. **Frontend** получает `initData` от Telegram WebApp
2. **Backend** валидирует HMAC-SHA256 подпись
3. **Success**: Пользователь аутентифицирован, данные доступны в handlers
4. **Error**: Доступ запрещен (401 Unauthorized)
## 📝 Требования к переменным окружения
Добавьте в `.env` файл:
```env
BOT_TOKEN=ваш_токен_бота_от_@BotFather
```
## 🛡️ Middleware
### Auth Middleware
```go
// Применяется ко всем защищенным маршрутам
app.Use(middleware.AuthMiddleware(middleware.AuthConfig{
BotToken: cfg.BotToken,
}))
```
### Получение данных пользователя в handler
```go
userData := middleware.GetTelegramUser(c)
if userData == nil {
return c.Status(fiber.StatusUnauthorized).JSON(...)
}
// Используем userData.ID, userData.FirstName и т.д.
```
## 📡 API Эндпоинты
### POST /api/auth/validate
Валидация initData без middleware (для инициализации)
**Request:**
```bash
curl -X POST http://localhost:8080/api/auth/validate \
-H "Content-Type: application/json" \
-d '{
"initData": "query_id=AAHdF6IQAAAAAN0XohDhrOrc&user=%7B%22id%22%3AYOUR_TELEGRAM_USER_ID%2C%22first_name%22%3A%22YOUR_FIRST_NAME%22%2C%22last_name%22%3A%22YOUR_LAST_NAME%22%2C%22username%22%3A%22YOUR_USERNAME%22%2C%22language_code%22%3A%22en%22%2C%22is_premium%22%3Atrue%2C%22allows_write_to_pm%22%3Atrue%7D&auth_date=1634567890&hash=YOUR_HASH_HERE..."
}'
```
**Response (200 OK):**
```json
{
"success": true,
"message": "Authentication successful",
"data": {
"id": YOUR_TELEGRAM_USER_ID,
"first_name": "John",
"last_name": "Doe",
"username": "johndoe",
"photo_url": "https://t.me/i/userpic/320/johndoe.jpg",
"auth_date": YOUR_AUTH_DATE,
"hash": "abcd1234..."
}
}
```
### GET /api/auth/me
Получение данных текущего аутентифицированного пользователя
**Request:**
```bash
curl -X GET http://localhost:8080/api/auth/me \
-H "X-Telegram-WebApp-Init-Data: ваш_init_data_здесь"
```
**Response (200 OK):**
```json
{
"success": true,
"message": "User data retrieved successfully",
"data": {
"id": YOUR_TELEGRAM_USER_ID,
"first_name": "John",
"last_name": "Doe",
"username": "johndoe",
"photo_url": "https://t.me/i/userpic/320/johndoe.jpg",
"auth_date": YOUR_AUTH_DATE,
"hash": "abcd1234..."
}
}
```
## 🔒 Защищенные эндпоинты
Все следующие эндпоинты требуют аутентификации:
### User Routes
- `GET /api/me` - профиль пользователя
- `GET /api/user/transactions` - история транзакций
- `GET /api/user/purchases` - история покупок
### Quiz Routes
- `GET /api/quizzes` - список викторин
- `GET /api/quizzes/:id` - детали викторины
- `POST /api/quizzes/:id/submit` - отправка ответов
- `GET /api/quizzes/:id/can-repeat` - проверка возможности повтора
### Reward Routes
- `GET /api/rewards` - список призов
- `POST /api/rewards/:id/purchase` - покупка приза
### QR Routes
- `POST /api/qr/validate` - валидация QR кода
## 🔄 Как использовать в фронтенде
### 1. Получение initData из Telegram WebApp
```javascript
// В вашем Telegram Mini App
const initData = window.Telegram.WebApp.initData;
```
### 2. Отправка на бэкенд
```javascript
// Вариант 1: Через заголовок (рекомендуется)
const response = await fetch('/api/qr/validate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Telegram-WebApp-Init-Data': initData
},
body: JSON.stringify({ payload: 'qr_token_here' })
});
// Вариант 2: Через body для /api/auth/validate
const response = await fetch('/api/auth/validate', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ initData })
});
```
### 3. Обработка ошибок
```javascript
if (!response.ok) {
if (response.status === 401) {
// Переадресация на страницу аутентификации
window.location.href = '/auth';
} else {
// Другая ошибка
console.error('Request failed:', response.statusText);
}
}
```
## ⚠️ Важные моменты
1. **Время жизни**: initData действителен 5 минут
2. **Безопасность**: Всегда проверяйте HMAC подпись на бэкенде
3. **Bot Token**: Храните в секрете, никогда в клиентском коде
4. **User ID**: Используйте `userData.ID` как уникальный идентификатор
## 🔧 Тестирование
### Генерация тестового initData
Используйте [Telegram WebApp Tools](https://telegram-web-app-tools.vercel.app/) для генерации тестовых initData.
### Пример curl с реальными данными
```bash
# Замените YOUR_INIT_DATA на реальные данные
curl -X POST http://localhost:8080/api/qr/validate \
-H "Content-Type: application/json" \
-H "X-Telegram-WebApp-Init-Data: YOUR_INIT_DATA" \
-d '{"payload": "test_qr_token"}'
```
## 🚀 Production Deployment
1. **HTTPS**: Обязательно используйте HTTPS в production
2. **Bot Token**: Используйте переменные окружения
3. **Rate Limiting**: Добавьте rate limiting для auth эндпоинтов
4. **Logging**: Логируйте неудачные попытки аутентификации
5. **Security**: Регулярно обновляйте зависимости
## 🔍 Отладка
### Распространенные ошибки
1. **401 Unauthorized**: Неверный initData или просрочен
2. **Hash verification failed**: Неверный bot token или поврежденные данные
3. **Missing Telegram init data**: Отсутствует заголовок или initData
4. **Auth data expired**: Данные старше 5 минут
### Debug режим
Для отладки можно временно отключить проверку времени:
```go
// В middleware/auth.go закомментируйте проверку времени
// if time.Since(authTime) > 5*time.Minute {
// return errors.New("auth data expired")
// }
```