#c #mariadb #fastcgi
#c #mariadb #fastcgi
Вопрос:
Я создаю программу для хранения информации о клиентах в базе данных. Я использую клиент mariadb на c mariadbpp от mariadbb. Поскольку я новичок в сетевом мире, я сначала создал консольное приложение, которое работало. Затем я попытался создать версию этого приложения на fastcgi.
Это код:
#include <fastcgi /request.hpp>
#include <fastcgi /manager.hpp>
//for json
#include <nlohmann/json.hpp>
//for database connection
#include <mariadb /account.hpp>
#include <mariadb /connection.hpp>
//for (cryptogrphic) password hashing
//#include <bcrypt/BCrypt.hpp>
//to get mariadb's password
#include <fstream>
class AddUser : public Fastcgipp::Request<char>
{
bool response(){
out << "Content-Type: application/json; charset=utf-8rnrn";
nlohmann::json json;
//iterators declared in order to check if the required variables are given
auto it_name = environment().gets.find("name"),
it_address = environment().gets.find("address"),
it_phoneNumber = environment().gets.find("phoneNumber"),
it_password = environment().gets.find("password");
/**
* Returning in case of an error because the following checks are preconditions and it
* does not make sense to continue processing if these are not met
*/
if(it_name == environment().gets.end() || it_address == environment().gets.end() ||
it_phoneNumber == environment().gets.end() || it_password == environment().gets.end()){
//give an error if anything is missing
json["error"] = "Unkown parameters";
out << json;
return true;
}
//otherwise get the name, address, etc
std::string name = it_name->second,
address = it_address->second,
phoneNumber = it_phoneNumber->second,
password = it_password->second;
//check if the phone number is 10 digits long
if(phoneNumber.size() != 10){
json["error"] = "Invalid phoneNumber";
out << json;
return true;
}
//check if the phone number only contains digits and not letters
for(const char c : phoneNumber){
if(c < '0' amp;amp; c > '9'){
json["error"] = "Invalid phoneNumber";
out << json;
return true;
}
}
//get the password
std::ifstream file("/home/Hemil/add-user.txt");
std::string acc_password;
std::getline(file, acc_password);
mariadb::account_ref acc = mariadb::account::create("localhost", "add-user", acc_password, "Customers");
mariadb::connection_ref con = mariadb::connection::create(acc);
/**
//input the credentials into the database
mariadb::statement_ref smt = con->create_statement("insert into Info(Name, Address, PhoneNumber, Password) values(?, ?, ?, ?)");
smt->set_string(0, name);
smt->set_string(1, address);
smt->set_string(2, phoneNumber);
//to hash the password
//BCrypt bcrypt;
//smt->set_string(3, bcrypt.generateHash(password));
smt->set_string(3, password);
/**
* Not returning in case of an error because these are errors on our side.
*/
/**
//execute returns the number of rows affected which should be one because we inserted one row
if(smt->execute() == 1){
//get the customer id
auto getCustomerId = con->create_statement("select LAST_INSERT_ID()");
auto result = getCustomerId->query();
if(result->next()){
uint64_t CustomerId = result->get_unsigned64(0);
json["error"] = nullptr;
json["CustomerID"] = CustomerId;
} else {
json["error"] = "Could not get the Customer ID";
}
} else {
json["error"] = "Could not insert into table";
}
*/
out << json;
return true;
}
};
int main(){
Fastcgipp::Manager<AddUser> manager;
manager.setupSignals();
manager.listen();
manager.start();
manager.join();
}
Существует странная проблема. В текущей ситуации (с закомментированной вставкой) он работает без ошибок, выводя null, как и должно быть, потому что nloh nam nn::json он никогда не назначался (по умолчанию используется null). Если я отменяю комментарий к этой вставке, я получаю ошибку внутреннего сервера 500. Это ошибка_log:
MariaDB Error(1045): Access denied for user 'add-user'@'localhost' (using password: NO)
In function: connect
In file /home/Hemil/Downloads/mariadbpp/src/connection.cpp
On line 109
terminate called after throwing an instance of 'mariadb::exception::connection'
what(): Access denied for user 'add-user'@'localhost' (using password: NO)
[Thu Mar 14 11:08:38.209250 2019] [fcgid:warn] [pid 8302:tid 139977899874048] [client 127.0.0.1:42144] mod_fcgid: error reading data, FastCGI server closed connection
[Thu Mar 14 11:08:38.209375 2019] [core:error] [pid 8302:tid 139977899874048] [client 127.0.0.1:42144] End of script output before headers: add-user.fcg
[Thu Mar 14 11:08:40.937823 2019] [fcgid:error] [pid 8300:tid 139978589235456] mod_fcgid: process /var/www/cgi-bin/add-user.fcg(8517) exit(communication error), get signal 6, possible coredump generated
Самое смешное, что я использую пароль.
Я отключил доступ к базе данных из сети. Я полагаю, это связано с тем, что Mariadb считает localhost удаленным запросом, который отключен.
P.S: Я знаю, что передавать пароль через GET не очень хорошая идея. Я должен использовать Post. Я изменю это.
Ответ №1:
Происходит что-то странное. Я обнаружил, что мне не удалось получить пароль из файла. Пароль был нулевой строкой. Вот как MariaDB пожаловался, что пароль не был использован. Я проверил это, введя пароль в метод create, и это работает.
Но ввод пароля в двоичный файл не является хорошей практикой безопасности, поэтому я ищу причину, по которой я не могу открыть файл.