Задать вопрос
@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();
  • Вопрос задан
  • 1014 просмотров
Подписаться 1 Простой 5 комментариев
Помогут разобраться в теме Все курсы
  • Skillfactory
    Профессия Fullstack веб-разработчик на JavaScript и PHP
    20 месяцев
    Далее
  • Хекслет
    PHP-разработчик
    10 месяцев
    Далее
  • Нетология
    Веб-разработчик с нуля: профессия с выбором специализации
    14 месяцев
    Далее
Пригласить эксперта
Ответы на вопрос 2
@Kokoulin
PHP/Go Разработчик
Вы всегда регистрируете нового пользователя у вас нет проверки на его существование.
У вас идет получение existing_user, а затем вы не проверяете его, а сходу создаете нового пользователя
Ответ написан
karabanov
@karabanov
Системный администратор
if (isset($_SESSION['user'])) {
    echo "User is logged in!"; // Этого здесь быть не должно
    header('Location: ./index.php');

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

Надо или обеспечить отсутствие какого либо вывода до отправки заголовков, либо буферизовать вывод.
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы
FoodSoul Калининград
от 180 000 до 250 000 ₽
IT-Spirit Москва
от 230 000 до 320 000 ₽
от 200 000 до 290 000 ₽