262 lines
9.1 KiB
Markdown
262 lines
9.1 KiB
Markdown
|
|
# План миграции SMS верификации в n8n
|
|||
|
|
|
|||
|
|
## Текущая логика (PHP)
|
|||
|
|
|
|||
|
|
### 1. Отправка SMS (`sms-verify.php?action=send`)
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌─────────────┐
|
|||
|
|
│ Frontend │
|
|||
|
|
│ (JS) │
|
|||
|
|
└──────┬──────┘
|
|||
|
|
│ POST: phonenumber
|
|||
|
|
▼
|
|||
|
|
┌─────────────────────┐
|
|||
|
|
│ sms-verify.php │
|
|||
|
|
│ action=send │
|
|||
|
|
└──────┬──────────────┘
|
|||
|
|
│
|
|||
|
|
├─► Нормализация номера (clear_phone)
|
|||
|
|
├─► Проверка rate limit (Redis)
|
|||
|
|
├─► Генерация кода (generateCode)
|
|||
|
|
├─► Сохранение в Redis (setex, 10 мин)
|
|||
|
|
├─► Отправка SMS → n8n webhook
|
|||
|
|
└─► Ответ: success
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. Проверка кода (`sms-verify.php?action=verify`)
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌─────────────┐
|
|||
|
|
│ Frontend │
|
|||
|
|
│ (JS) │
|
|||
|
|
└──────┬──────┘
|
|||
|
|
│ POST: phonenumber, code
|
|||
|
|
▼
|
|||
|
|
┌─────────────────────┐
|
|||
|
|
│ sms-verify.php │
|
|||
|
|
│ action=verify │
|
|||
|
|
└──────┬──────────────┘
|
|||
|
|
│
|
|||
|
|
├─► Нормализация номера
|
|||
|
|
├─► Проверка rate limit попыток
|
|||
|
|
├─► Чтение кода из Redis
|
|||
|
|
├─► Сравнение кодов
|
|||
|
|
├─► Удаление кода из Redis
|
|||
|
|
├─► Создание токена верификации
|
|||
|
|
└─► Ответ: success, token
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Новая логика (n8n)
|
|||
|
|
|
|||
|
|
### Workflow 1: Отправка SMS
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ Webhook │ POST /webhook/sms-send
|
|||
|
|
│ Trigger │ Body: { phonenumber: "+79262306381" }
|
|||
|
|
└────────┬────────┘
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ Function │ Нормализация номера
|
|||
|
|
│ (JS Code) │ phone.replace(/[() -+]/g, '').replace(/^(\+?7|8)/, '')
|
|||
|
|
└────────┬────────┘
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ Redis │ GET sms:ratelimit:send:9262306381
|
|||
|
|
│ (Get) │ Если >= 5 → ошибка
|
|||
|
|
└────────┬────────┘
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ Function │ Генерация кода
|
|||
|
|
│ (JS Code) │ Math.floor(100000 + Math.random() * 900000)
|
|||
|
|
└────────┬────────┘
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ Redis │ SETEX sms:code:9262306381 600 "106574"
|
|||
|
|
│ (Set) │
|
|||
|
|
└────────┬────────┘
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ Redis │ INCR sms:ratelimit:send:9262306381
|
|||
|
|
│ (Increment) │ EXPIRE 3600
|
|||
|
|
└────────┬────────┘
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ HTTP Request │ POST к SMS API
|
|||
|
|
│ (SMS Send) │ Body: { phone, text: "Код: 106574" }
|
|||
|
|
└────────┬────────┘
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ IF (error) │ Если ошибка → удалить код из Redis
|
|||
|
|
│ (Error Handle) │
|
|||
|
|
└────────┬────────┘
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ Respond to │ { success: true, message: "..." }
|
|||
|
|
│ Webhook │
|
|||
|
|
└─────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Workflow 2: Проверка кода
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ Webhook │ POST /webhook/sms-verify
|
|||
|
|
│ Trigger │ Body: { phonenumber: "+79262306381", code: "106574" }
|
|||
|
|
└────────┬────────┘
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ Function │ Нормализация номера
|
|||
|
|
│ (JS Code) │
|
|||
|
|
└────────┬────────┘
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ Redis │ GET sms:ratelimit:attempts:9262306381
|
|||
|
|
│ (Get) │ Если >= 10 → ошибка
|
|||
|
|
└────────┬────────┘
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ Redis │ INCR sms:ratelimit:attempts:9262306381
|
|||
|
|
│ (Increment) │ EXPIRE 900
|
|||
|
|
└────────┬────────┘
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ Redis │ GET sms:code:9262306381
|
|||
|
|
│ (Get) │ Если null → ошибка "Код не найден"
|
|||
|
|
└────────┬────────┘
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ IF │ Если code !== stored_code → ошибка "Неверный код"
|
|||
|
|
│ (Compare) │
|
|||
|
|
└────────┬────────┘
|
|||
|
|
│ (success)
|
|||
|
|
▼
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ Redis │ DEL sms:code:9262306381
|
|||
|
|
│ (Delete) │ DEL sms:ratelimit:attempts:9262306381
|
|||
|
|
└────────┬────────┘
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ Function │ Генерация токена
|
|||
|
|
│ (JS Code) │ crypto.randomBytes(32).toString('hex')
|
|||
|
|
└────────┬────────┘
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ Redis │ SETEX sms:verified:9262306381 3600 "token"
|
|||
|
|
│ (Set) │
|
|||
|
|
└────────┬────────┘
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ Respond to │ { success: true, token: "..." }
|
|||
|
|
│ Webhook │
|
|||
|
|
└─────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Пошаговая миграция
|
|||
|
|
|
|||
|
|
### Шаг 1: Создать workflows в n8n
|
|||
|
|
|
|||
|
|
1. Зайти в n8n: https://n8n.clientright.pro
|
|||
|
|
2. Создать новый workflow "SMS Send"
|
|||
|
|
3. Создать новый workflow "SMS Verify"
|
|||
|
|
4. Создать новый workflow "SMS Check Verified" (опционально)
|
|||
|
|
|
|||
|
|
### Шаг 2: Настроить Redis в n8n
|
|||
|
|
|
|||
|
|
- Добавить Redis credentials в n8n
|
|||
|
|
- Host: `crm.clientright.ru`
|
|||
|
|
- Port: `6379`
|
|||
|
|
- Password: (из .env)
|
|||
|
|
|
|||
|
|
### Шаг 3: Протестировать workflows
|
|||
|
|
|
|||
|
|
- Запустить тестовые запросы через Postman/curl
|
|||
|
|
- Проверить, что коды сохраняются в Redis
|
|||
|
|
- Проверить, что SMS отправляются
|
|||
|
|
|
|||
|
|
### Шаг 4: Изменить PHP код
|
|||
|
|
|
|||
|
|
**Вариант A: Прокси через PHP (проще)**
|
|||
|
|
```php
|
|||
|
|
// sms-verify.php просто перенаправляет на n8n
|
|||
|
|
$n8n_url = 'https://n8n.clientright.pro/webhook/sms-send';
|
|||
|
|
// ... curl запрос к n8n
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Вариант B: Прямой вызов n8n из JS (лучше)**
|
|||
|
|
```javascript
|
|||
|
|
// js/common.js
|
|||
|
|
$.ajax({
|
|||
|
|
url: 'https://n8n.clientright.pro/webhook/sms-send',
|
|||
|
|
// ...
|
|||
|
|
});
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Шаг 5: Удалить старую логику из PHP
|
|||
|
|
|
|||
|
|
- Удалить генерацию кода
|
|||
|
|
- Удалить работу с Redis (оставить только fallback на файлы, если нужно)
|
|||
|
|
- Оставить только проксирование запросов
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Преимущества
|
|||
|
|
|
|||
|
|
✅ **Визуализация** - видно весь процесс в n8n
|
|||
|
|
✅ **Логирование** - автоматические логи каждого шага
|
|||
|
|
✅ **Мониторинг** - видно ошибки и задержки
|
|||
|
|
✅ **Гибкость** - легко добавить новые шаги
|
|||
|
|
✅ **Тестирование** - можно тестировать каждый шаг отдельно
|
|||
|
|
✅ **Масштабируемость** - легко добавить несколько SMS провайдеров
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Примеры кода для n8n
|
|||
|
|
|
|||
|
|
### Нормализация номера (Function Node)
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
const phone = $input.item.json.phonenumber || '';
|
|||
|
|
const cleaned = phone
|
|||
|
|
.replace(/[() -]/g, '')
|
|||
|
|
.replace(/^(\+?7|8)/, '');
|
|||
|
|
|
|||
|
|
return { json: { phone_cleaned: cleaned } };
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Генерация кода (Function Node)
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
const code = Math.floor(100000 + Math.random() * 900000).toString();
|
|||
|
|
return { json: { code } };
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Генерация токена (Function Node)
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
const crypto = require('crypto');
|
|||
|
|
const token = crypto.randomBytes(32).toString('hex');
|
|||
|
|
return { json: { token } };
|
|||
|
|
```
|