База данных

Daniel_Govnocode

Активный
Автор темы
315
57
Версия MoonLoader
Другое
Добрый вечер. Нужно научиться работать с БД в луа. Видел что можно юзать MySQL, но там логин, пароль указывается в коде и кто угодно чо угодно может поменять в БД. Каким еще образом можно подключать БД?
 
Решение
Поконкретней можно? Примеры?
Давай по порядку.

I. Проблема
Ты сам её описал:
логин, пароль указывается в коде и кто угодно чо угодно может поменять в БД

II. Решение
Ты отправляешь запросы на сайт (к исходникам сайта доступа нет), сайт отправляет твой же запрос в базу данных. На обратном пути сайт получает ответ от БД и этот же ответ возвращает тебе в ответ на HTTP-запрос. Итог: твой пароль не хранится в самом скрипте, взломать нельзя.

III. Реализация
Сайт может быть написан на PHP.
1) О том, как отправлять запросы в БД — видеоролик по ссылке, всё крайне просто.
2) О том, как на PHP реагировать на HTTP запросы — вот статья.
3) О том, как на Lua отправлять HTTP запрос — статья на...

whyega52

Гений, миллионер, плейбой, долбаеб
Модератор
2,812
2,691
Добрый вечер. Нужно научиться работать с БД в луа. Видел что можно юзать MySQL, но там логин, пароль указывается в коде и кто угодно чо угодно может поменять в БД. Каким еще образом можно подключать БД?
подключаться к своему серверу и уже на нем делать работу с БД
 
  • Нравится
Реакции: Vintik и chapo

Дядя Энрик.

Активный
338
81
Добрый вечер. Нужно научиться работать с БД в луа. Видел что можно юзать MySQL, но там логин, пароль указывается в коде и кто угодно чо угодно может поменять в БД. Каким еще образом можно подключать БД?
Я через гугл таблицу юзаю бд, гении на кодерах скажут что говно способ, но он бесплатный, проблем у других с этим нет (с запросами) + гугл таблица всегда под рукой, быстро обрабатываются запросы. За год использования гугл таблиц я не увидел никаких проблем.
 
  • Эм
Реакции: Vintik

Fott

Простреленный
3,462
2,379
Я через гугл таблицу юзаю бд, гении на кодерах скажут что говно способ, но он бесплатный, проблем у других с этим нет (с запросами) + гугл таблица всегда под рукой, быстро обрабатываются запросы. За год использования гугл таблиц я не увидел никаких проблем.
qrekjijaaua.jpg
 

Vintik

Через тернии к звёздам
Проверенный
1,562
1,033
Поконкретней можно? Примеры?
Давай по порядку.

I. Проблема
Ты сам её описал:
логин, пароль указывается в коде и кто угодно чо угодно может поменять в БД

II. Решение
Ты отправляешь запросы на сайт (к исходникам сайта доступа нет), сайт отправляет твой же запрос в базу данных. На обратном пути сайт получает ответ от БД и этот же ответ возвращает тебе в ответ на HTTP-запрос. Итог: твой пароль не хранится в самом скрипте, взломать нельзя.

III. Реализация
Сайт может быть написан на PHP.
1) О том, как отправлять запросы в БД — видеоролик по ссылке, всё крайне просто.
2) О том, как на PHP реагировать на HTTP запросы — вот статья.
3) О том, как на Lua отправлять HTTP запрос — статья на БХ.
Примечание: для понимания как работать с PHP — этот видеоурок.

IV. Пример
1) Устанавливаем PHP (см. прим II части), пробуем сделать 1-й код для проверки:
PHP:
<html>
<body>
<p>
    <?php
    $num = 1;
    $num += 5;
    echo $num;
    ?>
</p>
</body>
</html>
Должно выводить "6" на странице (у меня работает). Если так, то идём дальше.

2) Простейшая программка, которая отправляет (на JS) и принимает (на PHP) POST-запрос.
Это простейший сайт, который отправляет запрос с полями { "login": "abc", "password": "123" }. Разумеется, поля и их значения могут быть любыми строками — именно это аргументы твоего запроса к БД.
Отправка POST-запроса (пример на JS):
<script>
    fetch("http://localhost:4000/web.php", {
        method: "POST",
        headers: {
            "Accept": "application/json",
            "Content-Type": "application/json"
        },
        body: JSON.stringify({ "login": "abc", "password": "123" })
    })
    .then(response => response.json())
    .then(data => document.write(JSON.stringify(data)))
</script>
В строке 11 data — это ответ на запрос. Оно переводит JSON в строку и выводит просто на страницу.

Далее простейший серверный PHP, который по указанным массивам аккаунтов проверяет, есть ли аккаунт с таким-то логином и паролем. Если да – выводит ответ «OK», иначе — «ERROR».
PHP:
<?php
$_POST = json_decode(file_get_contents('php://input'), true);

$accounts = 3;
$logins = array("abc", "admin", "whyega52");
$passwords = array("123", "admin", "qwerty");

$found = False;
for ($i = 0; $i < $accounts; $i++)
    if ($_POST["login"] == $logins[$i] && $_POST["password"] == $passwords[$i])
    {
        echo '{ "account" : "OK" }';
        $found = True;
    }
if (!$found)
    echo '{ "account" : "ERROR" }';
?>
Строка 2 объявляет переменную _POST, в которой содержатся все аргументы POST-запроса и их значения. Дальше работаешь уже с ними. В конце echo "text"; выводит написанный текст на страницу (это ответ на POST запрос), который преобразуется в JSON программкой выше и выводится на исходную страницу (ту, с которой был направлен запрос).
1728326080987.png
1728326098853.png

Сразу замечу, что исходный код PHP не видно, следовательно логин и пароль от MySQL не смогут найти:
1728326218208.png
1728326228010.png

3) Работа с MySQL базой данных.
Эту часть я, пожалуй, оставлю тебе. В видосе, который я скинул, всё подробно рассказано. У меня просто нету БД и настраивать лень, поэтому не буду этим заниматься сейчас.
1728326408814.png

4) Асинхронный* запрос на Lua.
* Асинхронный — это значит, что он выполняется «в фоновом режиме», не фризя твою игру на пару секунд.
У меня уже давно не ни SA-MP, да что уж там, ни GTA — поэтому проверить код не смогу, но +- верно написать попробую.
Куда-то в начало кода инициализацию:
local copas = require 'copas'
local http = require 'copas.http'
local requests = require 'requests'
requests.http_socket, requests.https_socket = http, http

function httpRequest(method, request, args, handler) -- lua-requests
    -- start polling task
    if not copas.running then
        copas.running = true
        lua_thread.create(function()
            wait(0)
            while not copas.finished() do
                local ok, err = copas.step(0)
                if ok == nil then error(err) end
                wait(0)
            end
            copas.running = false
        end)
    end
    -- do request
    if handler then
        return copas.addthread(function(m, r, a, h)
            copas.setErrorHandler(function(err) h(nil, err) end)
            h(requests.request(m, r, a))
        end, method, request, args, handler)
    else
        local results
        local thread = copas.addthread(function(m, r, a)
            copas.setErrorHandler(function(err) results = {nil, err} end)
            results = table.pack(requests.request(m, r, a))
        end, method, request, args)
        while coroutine.status(thread) ~= 'dead' do wait(0) end
        return table.unpack(results)
    end
end
Сам POST-запрос:
local response, err = httpRequest('POST', {
    'http://localhost:4000/web.php',
    data = '{ "login": "admin", "password": "admin" }'
})
if err then error(err) end
local json_data = response.json()
print(json_data.data) -- ответ будет что-то типа «{"account":"OK"}»

5) Итог:
1. Делаешь код Lua и пробуешь связаться с сервером на PHP (я ж даже не знаю что ты хочешь в БД проверять/получать, но поля (те, которые login и password) и их значения ты можешь делать любые и любой длины).
2. Пытаешься прикрутить MySQL к твоему коду PHP, это просто, 5 минут дела.
3. Хостишь. Тут пусть скажут профессионалы, никогда не хостил PHP сервер. Какой-то дешёвый хостинг для сайтов, туда просто закидываешь .php файл и всё.
1728327274995.png
* JS я использовал потому, что нет возможности сразу на Lua.
+ если не будет получаться отправлять запрос, то можно с помощью JS определить в чём ошибка — в Lua или в PHP.
Удачи)
 
Последнее редактирование:

Daniel_Govnocode

Активный
Автор темы
315
57
Давай по порядку.

I. Проблема
Ты сам её описал:


II. Решение
Ты отправляешь запросы на сайт (к исходникам сайта доступа нет), сайт отправляет твой же запрос в базу данных. На обратном пути сайт получает ответ от БД и этот же ответ возвращает тебе в ответ на HTTP-запрос. Итог: твой пароль не хранится в самом скрипте, взломать нельзя.

III. Реализация
Сайт может быть написан на PHP.
1) О том, как отправлять запросы в БД — видеоролик по ссылке, всё крайне просто.
2) О том, как на PHP реагировать на HTTP запросы — вот статья.
3) О том, как на Lua отправлять HTTP запрос — статья на БХ.
Примечание: для понимания как работать с PHP — этот видеоурок.

IV. Пример
1) Устанавливаем PHP (см. прим II части), пробуем сделать 1-й код для проверки:
PHP:
<html>
<body>
<p>
    <?php
    $num = 1;
    $num += 5;
    echo $num;
    ?>
</p>
</body>
</html>
Должно выводить "6" на странице (у меня работает). Если так, то идём дальше.

2) Простейшая программка, которая отправляет (на JS) и принимает (на PHP) POST-запрос.
Это простейший сайт, который отправляет запрос с полями { "login": "abc", "password": "123" }. Разумеется, поля и их значения могут быть любыми строками — именно это аргументы твоего запроса к БД.
Отправка POST-запроса (пример на JS):
<script>
    fetch("http://localhost:4000/web.php", {
        method: "POST",
        headers: {
            "Accept": "application/json",
            "Content-Type": "application/json"
        },
        body: JSON.stringify({ "login": "abc", "password": "123" })
    })
    .then(response => response.json())
    .then(data => document.write(JSON.stringify(data)))
</script>
В строке 11 data — это ответ на запрос. Оно переводит JSON в строку и выводит просто на страницу.

Далее простейший серверный PHP, который по указанным массивам аккаунтов проверяет, есть ли аккаунт с таким-то логином и паролем. Если да – выводит ответ «OK», иначе — «ERROR».
PHP:
<?php
$_POST = json_decode(file_get_contents('php://input'), true);

$accounts = 3;
$logins = array("abc", "admin", "whyega52");
$passwords = array("123", "admin", "qwerty");

$found = False;
for ($i = 0; $i < $accounts; $i++)
    if ($_POST["login"] == $logins[$i] && $_POST['password'] == $passwords[$i])
    {
        echo '{ "account" : "OK" }';
        $found = True;
    }
if (!$found)
    echo '{ "account" : "ERROR" }';
?>
Строка 2 объявляет переменную _POST, в которой содержатся все аргументы POST-запроса и их значения. Дальше работаешь уже с ними. В конце echo "text"; выводит написанный текст на страницу (это ответ на POST запрос), который преобразуется в JSON программкой выше и выводится на исходную страницу (ту, с которой был направлен запрос).

Сразу замечу, что исходный код PHP не видно, следовательно логин и пароль от MySQL не смогут найти:

3) Работа с MySQL базой данных.
Эту часть я, пожалуй, оставлю тебе. В видосе, который я скинул, всё подробно рассказано. У меня просто нету БД и настраивать лень, поэтому не буду этим заниматься сейчас.

4) Асинхронный* запрос на Lua.
* Асинхронный — это значит, что он выполняется «в фоновом режиме», не фризя твою игру на пару секунд.
У меня уже давно не ни SA-MP, да что уж там, ни GTA — поэтому проверить код не смогу, но +- верно написать попробую.
Куда-то в начало кода инициализацию:
local copas = require 'copas'
local http = require 'copas.http'
local requests = require 'requests'
requests.http_socket, requests.https_socket = http, http

function httpRequest(method, request, args, handler) -- lua-requests
    -- start polling task
    if not copas.running then
        copas.running = true
        lua_thread.create(function()
            wait(0)
            while not copas.finished() do
                local ok, err = copas.step(0)
                if ok == nil then error(err) end
                wait(0)
            end
            copas.running = false
        end)
    end
    -- do request
    if handler then
        return copas.addthread(function(m, r, a, h)
            copas.setErrorHandler(function(err) h(nil, err) end)
            h(requests.request(m, r, a))
        end, method, request, args, handler)
    else
        local results
        local thread = copas.addthread(function(m, r, a)
            copas.setErrorHandler(function(err) results = {nil, err} end)
            results = table.pack(requests.request(m, r, a))
        end, method, request, args)
        while coroutine.status(thread) ~= 'dead' do wait(0) end
        return table.unpack(results)
    end
end
Сам POST-запрос:
local response, err = httpRequest('POST', {
    'http://localhost:4000/web.php',
    data = '{ "login": "admin", "password": "admin" }'
})
if err then error(err) end
local json_data = response.json()
print(json_data.data) -- ответ будет что-то типа «{"account":"OK"}»

5) Итог:
1. Делаешь код Lua и пробуешь связаться с сервером на PHP (я ж даже не знаю что ты хочешь в БД проверять/получать, но поля (те, которые login и password) и их значения ты можешь делать любые и любой длины).
2. Пытаешься прикрутить MySQL к твоему коду PHP, это просто, 5 минут дела.
3. Хостишь. Тут пусть скажут профессионалы, никогда не хостил PHP сервер. Какой-то дешёвый хостинг для сайтов, туда просто закидываешь .php файл и всё.
* JS я использовал потому, что нет возможности сразу на Lua.
+ если не будет получаться отправлять запрос, то можно с помощью JS определить в чём ошибка — в Lua или в PHP.
Удачи)
Фигасе настрочил, утром почитаю. А так спасибо огромное!
 
  • Нравится
Реакции: Vintik

я котик

Участник
19
23
Далее простейший серверный PHP, который по указанным массивам аккаунтов проверяет, есть ли аккаунт с таким-то логином и паролем. Если да – выводит ответ «OK», иначе — «ERROR».
Накалякал пример с использованием MySQL.
В базе данных происходит поиск пользователя по никнейму, далее сверяется пароль и выдается result = true. В случае, если пароль неправильный - выдается ошибка 400 и result = false. Если пользователя не существует - выдается ошибка 404 и result = false.
PHP:
<?php
/**
 * Подключение к базе данных (https://www.php.net/manual/en/mysqli.construct.php)
 * @param string $MYSQL_SERVER Сервер MySQL (обычно это localhost)
 * @param string $MYSQL_USERNAME Имя пользователя MySQL
 * @param string $MYSQL_PASSWORD Пароль пользователя MySQL
 * @param string $MYSQL_DATABASE База данных пользователя MySQL
 * @return mysqli
 * @throws Exception
 */
function db_connect(string $MYSQL_SERVER, string $MYSQL_USERNAME, string $MYSQL_PASSWORD, string $MYSQL_DATABASE) : mysqli {
    $connect = mysqli_connect($MYSQL_SERVER, $MYSQL_USERNAME, $MYSQL_PASSWORD, $MYSQL_DATABASE) or die("Error: " . mysqli_error($connect));
    if(!mysqli_set_charset($connect, "utf8mb4"))
        die("Error: " . mysqli_error($connect));
    return $connect;
}
/**
 * Получает информацию о пользователе из базы данных
 * @param mysqli $mysqli Подключение MySQL
 * @param string $nickname Никнейм пользователя
 * @return array
 * @throws Exception
 */
function getUser(mysqli $mysqli, string $username) : array {
    $prepare = $mysqli->prepare("SELECT * FROM users WHERE username = ?");
    $prepare->bind_param("s", $username);
    $prepare->execute();
    $result = $prepare->get_result->fetch_all(MYSQLI_ASSOC);
    $prepare->close();
    return $result;
}
ini_set("display_errors", false); # Чтобы не появлялись серверные ошибки у пользователя
ini_set("display_startup_errors", false); # Чтобы не появлялись серверные ошибки у пользователя
header("Content-Type: application/json");
$mysqli = db_connect("localhost", "username", "password", "database"); # Подключаемся к базе
$_POST = json_decode(file_get_contents("php://input"), true); # Читаем JSON
$user = getUser($mysqli, $_POST["username"]); # Поиск пользователя
if(!empty($user)){
    if($user["password"] === $_POST["password"]){
        http_response_code(200); # Необязательно
        die(json_encode(["result" => true]));
    } else {
        http_response_code(400);
        die(json_encode(["result" => false]));
    }
} else {
    http_response_code(404);
    die(json_encode(["result" => false]));
}
Не везде написаны комментарии, поэтому про функции можешь прочитать на php.net (просто вбиваешь в поиск название функции).
 
Последнее редактирование:
  • Нравится
Реакции: Vintik

Daniel_Govnocode

Активный
Автор темы
315
57
Давай по порядку.

I. Проблема
Ты сам её описал:


II. Решение
Ты отправляешь запросы на сайт (к исходникам сайта доступа нет), сайт отправляет твой же запрос в базу данных. На обратном пути сайт получает ответ от БД и этот же ответ возвращает тебе в ответ на HTTP-запрос. Итог: твой пароль не хранится в самом скрипте, взломать нельзя.

III. Реализация
Сайт может быть написан на PHP.
1) О том, как отправлять запросы в БД — видеоролик по ссылке, всё крайне просто.
2) О том, как на PHP реагировать на HTTP запросы — вот статья.
3) О том, как на Lua отправлять HTTP запрос — статья на БХ.
Примечание: для понимания как работать с PHP — этот видеоурок.

IV. Пример
1) Устанавливаем PHP (см. прим II части), пробуем сделать 1-й код для проверки:
PHP:
<html>
<body>
<p>
    <?php
    $num = 1;
    $num += 5;
    echo $num;
    ?>
</p>
</body>
</html>
Должно выводить "6" на странице (у меня работает). Если так, то идём дальше.

2) Простейшая программка, которая отправляет (на JS) и принимает (на PHP) POST-запрос.
Это простейший сайт, который отправляет запрос с полями { "login": "abc", "password": "123" }. Разумеется, поля и их значения могут быть любыми строками — именно это аргументы твоего запроса к БД.
Отправка POST-запроса (пример на JS):
<script>
    fetch("http://localhost:4000/web.php", {
        method: "POST",
        headers: {
            "Accept": "application/json",
            "Content-Type": "application/json"
        },
        body: JSON.stringify({ "login": "abc", "password": "123" })
    })
    .then(response => response.json())
    .then(data => document.write(JSON.stringify(data)))
</script>
В строке 11 data — это ответ на запрос. Оно переводит JSON в строку и выводит просто на страницу.

Далее простейший серверный PHP, который по указанным массивам аккаунтов проверяет, есть ли аккаунт с таким-то логином и паролем. Если да – выводит ответ «OK», иначе — «ERROR».
PHP:
<?php
$_POST = json_decode(file_get_contents('php://input'), true);

$accounts = 3;
$logins = array("abc", "admin", "whyega52");
$passwords = array("123", "admin", "qwerty");

$found = False;
for ($i = 0; $i < $accounts; $i++)
    if ($_POST["login"] == $logins[$i] && $_POST["password"] == $passwords[$i])
    {
        echo '{ "account" : "OK" }';
        $found = True;
    }
if (!$found)
    echo '{ "account" : "ERROR" }';
?>
Строка 2 объявляет переменную _POST, в которой содержатся все аргументы POST-запроса и их значения. Дальше работаешь уже с ними. В конце echo "text"; выводит написанный текст на страницу (это ответ на POST запрос), который преобразуется в JSON программкой выше и выводится на исходную страницу (ту, с которой был направлен запрос).

Сразу замечу, что исходный код PHP не видно, следовательно логин и пароль от MySQL не смогут найти:

3) Работа с MySQL базой данных.
Эту часть я, пожалуй, оставлю тебе. В видосе, который я скинул, всё подробно рассказано. У меня просто нету БД и настраивать лень, поэтому не буду этим заниматься сейчас.

4) Асинхронный* запрос на Lua.
* Асинхронный — это значит, что он выполняется «в фоновом режиме», не фризя твою игру на пару секунд.
У меня уже давно не ни SA-MP, да что уж там, ни GTA — поэтому проверить код не смогу, но +- верно написать попробую.
Куда-то в начало кода инициализацию:
local copas = require 'copas'
local http = require 'copas.http'
local requests = require 'requests'
requests.http_socket, requests.https_socket = http, http

function httpRequest(method, request, args, handler) -- lua-requests
    -- start polling task
    if not copas.running then
        copas.running = true
        lua_thread.create(function()
            wait(0)
            while not copas.finished() do
                local ok, err = copas.step(0)
                if ok == nil then error(err) end
                wait(0)
            end
            copas.running = false
        end)
    end
    -- do request
    if handler then
        return copas.addthread(function(m, r, a, h)
            copas.setErrorHandler(function(err) h(nil, err) end)
            h(requests.request(m, r, a))
        end, method, request, args, handler)
    else
        local results
        local thread = copas.addthread(function(m, r, a)
            copas.setErrorHandler(function(err) results = {nil, err} end)
            results = table.pack(requests.request(m, r, a))
        end, method, request, args)
        while coroutine.status(thread) ~= 'dead' do wait(0) end
        return table.unpack(results)
    end
end
Сам POST-запрос:
local response, err = httpRequest('POST', {
    'http://localhost:4000/web.php',
    data = '{ "login": "admin", "password": "admin" }'
})
if err then error(err) end
local json_data = response.json()
print(json_data.data) -- ответ будет что-то типа «{"account":"OK"}»

5) Итог:
1. Делаешь код Lua и пробуешь связаться с сервером на PHP (я ж даже не знаю что ты хочешь в БД проверять/получать, но поля (те, которые login и password) и их значения ты можешь делать любые и любой длины).
2. Пытаешься прикрутить MySQL к твоему коду PHP, это просто, 5 минут дела.
3. Хостишь. Тут пусть скажут профессионалы, никогда не хостил PHP сервер. Какой-то дешёвый хостинг для сайтов, туда просто закидываешь .php файл и всё.
* JS я использовал потому, что нет возможности сразу на Lua.
+ если не будет получаться отправлять запрос, то можно с помощью JS определить в чём ошибка — в Lua или в PHP.
Удачи)
Короче руки только дошли. Отправляю запрос и в ответ получаю:

HTML:
<html><body><script type="text/javascript" src="/aes.js" ></script><script>function toNumbers(d){var e=[];d.replace(/(..)/g,function(d){e.push(parseInt(d,16))});return e}function toHex(){for(var d=[],d=1==arguments.length&&arguments[0].constructor==Array?arguments[0]:arguments,e="",f=0;f<d.length;f++)e+=(16>d[f]?"0":"")+d[f].toString(16);return e.toLowerCase()}var a=toNumbers("f655ba9d09a112d4968c63579db590b4"),b=toNumbers("98344c2eee86c3994890592585b49f80"),c=toNumbers("441c86912dc06161c8e51a2daf74b8fd");document.cookie="__test="+toHex(slowAES.decrypt(c,2,a,b))+"; expires=Thu, 31-Dec-37 23:55:55 GMT; path=/"; location.href="http://mvdhelpertest.byethost4.com/test.php?i=1";</script><noscript>This site requires Javascript to work, please enable Javascript in your browser or use a browser with Javascript support</noscript></body></html>
Чо делать?