Задать вопрос
@Chesterfield25

Как решить проблему с сессиями?

У меня есть мини приложение в телеграмм, проблемы с сессиями в том, что после регистрации перенаправляет на index.php но не сразу а после перезагрузки приложения, а вот если пользователь уже есть в бд то перенаправление не происходит вообще.

auth.php
<?php
session_start();

header('Access-Control-Allow-Origin: *'); // Разрешает доступ с любого источника
header('Access-Control-Allow-Methods: POST, GET, OPTIONS'); // Разрешает методы POST, GET, OPTIONS
header('Access-Control-Allow-Headers: Content-Type'); // Разрешает использование заголовка Content-Type
header('Cache-Control: no-cache, no-store, must-revalidate');

if (isset($_SESSION['user'])) {
    echo "User is logged in!";
    header('Location: ./index.php');
    exit();
} else {
    echo "User is not logged in.";
}

auth_post.php
<?php
session_start(); // Инициализация сессии

header('Access-Control-Allow-Origin: *'); // Разрешает доступ с любого источника
header('Access-Control-Allow-Methods: POST, GET, OPTIONS'); // Разрешает методы POST, GET, OPTIONS
header('Access-Control-Allow-Headers: Content-Type'); // Разрешает использование заголовка Content-Type
header('Cache-Control: no-cache, no-store, must-revalidate');

// Подключаем конфигурацию базы данных
require_once 'config.php';

// Устанавливаем заголовки для обработки JSON
header('Content-Type: application/json');

// Проверяем метод запроса
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // Получаем JSON-данные из тела запроса
    $inputJSON = file_get_contents('php://input');
    $data = json_decode($inputJSON, true);

    // Проверяем корректность полученных данных
    if (json_last_error() === JSON_ERROR_NONE && isset($data['user'])) {
        // Извлекаем данные пользователя
        $user = $data['user'];
        $referrer_id = $data['referrer_id'] ?? null;
        $ref_url = $data['ref_url'] ?? null;
        $auth_date = $data['auth_date'] ?? null;
        $hash = $data['hash'] ?? null;
        $wallet_address = $data['wallet_address'] ?? null;

        try {
            // Проверяем, существует ли пользователь
            $stmt_check_user = $pdo->prepare("SELECT * FROM users WHERE user_id = ?");
            $stmt_check_user->execute([
                $user['id']
            ]);
            $existing_user = $stmt_check_user->fetch(PDO::FETCH_ASSOC);

                // Если пользователь не существует, регистрируем его
                $pdo->beginTransaction();
                $stmt_insert_user = $pdo->prepare("
                    INSERT INTO users (user_id, first_name, last_name, username, language_code, ref_url, auth_date, hash, wallet_address)
                    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
                ");
                $stmt_insert_user->execute([
                    $user['id'],
                    $user['first_name'],
                    $user['last_name'],
                    $user['username'],
                    $user['language_code'],
                    $ref_url,
                    $auth_date,
                    $hash,
                    $wallet_address
                ]);

                // Добавляем реферальные данные, если они есть
                if ($referrer_id) {
                    $stmt_insert_referral = $pdo->prepare("
                        INSERT INTO referral (referrer_id, user_id)
                        VALUES (?, ?)
                    ");
                    $stmt_insert_referral->execute([$referrer_id, $user['id']]);
                }
                $pdo->commit();


            // Создаём сессию независимо от авторизации или регистрации
            $_SESSION['user'] = [
                'id' => $existing_user['id'] ?? $user['id'], // Используем ID зарегистрированного пользователя
                'language_code' => $existing_user['language_code'] ?? $user['language_code'],
                'wallet_address' => $existing_user['wallet_address'] ?? $wallet_address
            ];

            // Перенаправляем на index.php
            // Отправляем успешный ответ
            echo json_encode(['status' => 'success']);
            exit();

        } catch (Exception $e) {
            // Откат транзакции при ошибке
            $pdo->rollBack();
            http_response_code(500);
            echo json_encode(['success' => false, 'message' => $e->getMessage()]);
        }
    } else {
        // Неверные данные
        http_response_code(400);
        echo json_encode(['success' => false, 'message' => 'Invalid JSON data']);
    }
} else {
    // Неверный метод запроса
    http_response_code(405);
    echo json_encode(['success' => false, 'message' => 'Method not allowed']);
}
?>

main.js
async function init() {
    const tonConnectUI = new TON_CONNECT_UI.TonConnectUI({
        manifestUrl: 'https://criptopays.net/coupon/tonconnect-manifest.json',
        buttonRootId: 'connect-wallet'
    });

    // Проверка доступности Telegram WebApp API
    if (!window.Telegram || !window.Telegram.WebApp) {
        console.error('Telegram WebApp API недоступен.');
        return;
    }

    const tg = window.Telegram.WebApp;
    const userInfo = tg.initDataUnsafe.user;

    // Функция для получения значения параметра
    function getQueryParam(param) {
        const urlParams = new URLSearchParams(window.location.search);
        return urlParams.get(param);
    }

    // Извлекаем значение параметра tgWebAppStartParam для десктоп версии
    const startAppParamDesktop = getQueryParam('tgWebAppStartParam');

    // Извлекаем значение параметра tgWebAppStartParam для андроид версии
    const initData = Telegram.WebApp.initDataUnsafe;
    const startAppParamAndroid = initData.start_param;

    // Получаем реферера из параметра start
    const referrerId = startAppParamDesktop || startAppParamAndroid || null;  // Здесь должно быть значение параметра start
    console.log('Referrer ID:', referrerId);

    // Создаем реферальную ссылку
    const referralLink = `https://t.me/TestTgMini_bot/testcypay?startapp=${userInfo.id}`;
    console.log('Referral Link:', referralLink);

    // Подписка на изменения статуса подключения кошелька
    const unsubscribe = tonConnectUI.onStatusChange(async (walletAndwalletInfo) => {
    const currentAccount = walletAndwalletInfo?.account;
    const currentWalletInfo = walletAndwalletInfo?.walletInfo;
    const isConnected = tonConnectUI.connected;

        if (isConnected) {
            console.log("Текущий аккаунт:", currentAccount);

            // Формируем данные для отправки на сервер
            const usersData = {
                query_id: tg.initDataUnsafe.query_id,
                user: {
                    id: userInfo.id,
                    first_name: userInfo.first_name,
                    last_name: userInfo.last_name,
                    username: userInfo.username,
                    language_code: userInfo.language_code
                },
                referrer_id: referrerId,
                ref_url: referralLink,
                auth_date: tg.initDataUnsafe.auth_date,
                hash: tg.initDataUnsafe.hash,
                wallet_address: currentAccount.address
            };

            console.log('Generated User Data:', usersData);

            // Отправка данных на сервер
            await sendUserDataToDB(usersData);
        } else {
            // Запрос к серверу для очистки сессии
                fetch('./logout.php', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    }
                })
                .then(response => response.json())
                .then(data => {
                    if (data.status === 'success') {
                        console.log('Сессия успешно завершена на сервере.');
                        // Перенаправление на auth.php
                        window.location.href = './auth.php';
                    } else {
                        console.error('Ошибка при завершении сессии на сервере.');
                    }
                })
                .catch(error => {
                    console.error('Ошибка сети при запросе на logout.php:', error);
                });
        }
    });
}

// Функция для отправки данных на сервер
async function sendUserDataToDB(usersData) {
    try {
        const response = await fetch('./auth_post.php', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(usersData)
        });

        if (response.ok) {
            const data = await response.json();
            if (data.status === 'success') {
                console.log('Пользователь успешно авторизован.');
                window.location.href = './index.php'; // Перенаправление на указанный URL
            } else {
                console.error('Ошибка авторизации:', data);
            }
        } else {
            console.error('Ошибка сервера:', await response.text());
        }
    } catch (error) {
        console.error('Ошибка при отправке данных:', error);
    }
}


// Инициализация
init();
  • Вопрос задан
  • 133 просмотра
Подписаться 1 Простой 5 комментариев
Решения вопроса 1
karabanov
@karabanov
Системный администратор
if (isset($_SESSION['user'])) {
    echo "User is logged in!"; // Этого здесь быть не должно
    header('Location: ./index.php');

Заголовки отправляются до тела ответа, потом отправлять их бесполезно. В логах наверняка Fatal есть на этот счёт. Пробелов или иных символов перед <?php тоже быть не должно.

Надо или обеспечить отсутствие какого либо вывода до отправки заголовков, либо буферизовать вывод.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@Kokoulin
PHP/Go Разработчик
Вы всегда регистрируете нового пользователя у вас нет проверки на его существование.
У вас идет получение existing_user, а затем вы не проверяете его, а сходу создаете нового пользователя
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы