0

我正在制作一个将客户信息存储在数据库中的程序。我正在使用 mariadb 的 c++ 客户端mariadbpp。因为我是网络世界的新手,所以我首先制作了一个可以运行的控制台应用程序。然后我尝试制作该应用程序的 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-8\r\n\r\n";

        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' && 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,因为它从未分配过 nlohnamnn::json (默认为 null)。如果我取消注释该插入,我会收到 500 内部服务器错误。这是错误日志:

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 计为禁用的远程请求。

PS:我知道通过 GET 传递密码不是一个好主意。我应该使用邮政。我会改变它。

4

1 回答 1

0

有什么奇怪的。我发现我无法从文件中获取密码。密码是一个空字符串。这就是 MariaDB 抱怨未使用密码的方式。我通过将密码放入 create 方法来验证这一点,它可以工作。

但是将密码放在二进制文件中并不是一个好的安全做法,所以我正在寻找为什么我无法打开文件。

于 2019-03-15T04:16:39.770 回答