Files
DLE/backend/server.js

172 lines
4.9 KiB
JavaScript
Raw 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.

const express = require('express');
const cors = require('cors');
const session = require('express-session');
const { SiweMessage, generateNonce } = require('siwe');
const path = require('path');
const app = express();
// Конфигурация CORS для работы с frontend
app.use(cors({
origin: ['http://localhost:5174', 'http://127.0.0.1:5173', 'http://localhost:5173'],
credentials: true,
methods: ['GET', 'POST'],
allowedHeaders: ['Content-Type', 'Accept']
}));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// Настройка сессий
app.use(session({
name: 'siwe-dapp',
secret: "siwe-dapp-secret",
resave: true,
saveUninitialized: true,
cookie: {
secure: false,
sameSite: 'lax',
maxAge: 24 * 60 * 60 * 1000 // 24 часа
}
}));
// Логирование запросов
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
next();
});
// Генерация nonce
app.get('/nonce', (req, res) => {
try {
req.session.nonce = generateNonce();
console.log('Сгенерирован новый nonce:', req.session.nonce);
res.setHeader('Content-Type', 'application/json');
res.status(200).json({ nonce: req.session.nonce });
} catch (error) {
console.error('Ошибка генерации nonce:', error);
res.status(500).json({ error: 'Internal Server Error' });
}
});
// Верификация сообщения
app.post('/verify', async (req, res) => {
try {
const { signature, message } = req.body;
console.log('Получен запрос на верификацию:', {
signature: signature?.slice(0, 20) + '...',
message,
sessionNonce: req.session.nonce
});
if (!req.session.nonce) {
console.error('Сессия не содержит nonce');
throw new Error('Invalid session');
}
let siweMessage;
try {
siweMessage = new SiweMessage(message);
const fields = await siweMessage.validate(signature);
if (fields.nonce !== req.session.nonce) {
console.error('Nonce не совпадает');
throw new Error('Invalid nonce');
}
console.log('Сообщение успешно верифицировано');
req.session.siwe = fields;
req.session.authenticated = true;
req.session.nonce = null;
res.json({
success: true,
address: fields.address
});
} catch (error) {
console.error('Ошибка валидации сообщения:', error);
req.session.authenticated = false;
req.session.siwe = null;
req.session.nonce = null;
throw error;
}
} catch (error) {
console.error('Ошибка верификации:', error);
res.status(400).json({
success: false,
error: error.message
});
}
});
// Получение сессии
app.get('/session', (req, res) => {
try {
res.json({
authenticated: !!req.session.authenticated,
address: req.session.siwe?.address
});
} catch (error) {
console.error('Ошибка получения сессии:', error);
res.status(500).json({ error: 'Internal Server Error' });
}
});
// Выход
app.get('/signout', (req, res) => {
try {
req.session.destroy((err) => {
if (err) {
console.error('Ошибка при удалении сессии:', err);
return res.status(500).json({ error: 'Failed to destroy session' });
}
res.status(200).json({ success: true });
});
} catch (error) {
console.error('Ошибка выхода:', error);
res.status(500).json({ error: 'Internal Server Error' });
}
});
// Базовый маршрут
app.get('/', (req, res) => {
res.json({
status: 'ok',
endpoints: {
nonce: 'GET /nonce',
verify: 'POST /verify',
session: 'GET /session',
signout: 'GET /signout'
}
});
});
// Обработка 404
app.use((req, res) => {
console.log(`404: ${req.method} ${req.url}`);
res.status(404).json({
error: 'Not Found',
message: `Endpoint ${req.method} ${req.url} не существует`
});
});
// Обработка ошибок
app.use((err, req, res, next) => {
console.error('Ошибка сервера:', err);
res.status(500).json({
error: 'Internal Server Error',
message: err.message
});
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`SIWE сервер запущен на порту ${PORT}`);
console.log('Доступные эндпоинты:');
console.log(' GET / - Информация о сервере');
console.log(' GET /nonce - Получить nonce');
console.log(' POST /verify - Верифицировать сообщение');
console.log(' GET /session - Получить текущую сессию');
console.log(' GET /signout - Выйти из системы');
});