how do i solve the CORS problem on cpp code?

468 Views Asked by At

i need to do get and post request , the get request works without problems but every time i do post request using the frontend (react/axios) it gives me this errors : Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8000/ethernetdata. (Reason: expected ‘true’ in CORS header ‘Access-Control-Allow-Credentials’).

XHRPOST http://localhost:8000/ethernetdata

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8000/ethernetdata. (Reason: CORS request did not succeed). Status code: (null).


but when i do post or get request using postman it works without problems this is my c++ server code :

#include <crow.h>
#include <iostream>
#include <sqlite3.h>
#include <nlohmann/json.hpp>


using json = nlohmann::json;

static int callback(void *data, int argc, char **argv, char **azColName){
json *result = reinterpret_cast<json*>(data);
json row;
for(int i=0; i<argc; i++){
    row[azColName[i]] = argv[i] ? argv[i] : "";
}
result->push_back(row);
return 0;
}

int main() {
crow::SimpleApp app;

sqlite3 *db;
int rc = sqlite3_open_v2("/home/khairy/work/eventsenderwebserver/Backend/db/data.db", &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr);
if (rc != SQLITE_OK) {
    std::cerr << "Cannot open database: " << sqlite3_errmsg(db) << std::endl;
    sqlite3_close(db);
    return 1;
}

const char* create_table_sql =
    "CREATE TABLE IF NOT EXISTS ethernetdata ("
    "id INTEGER PRIMARY KEY,"
    "ip TEXT NOT NULL,"
    "netmask TEXT NOT NULL,"
    "router TEXT NOT NULL,"
    "dns1 TEXT NOT NULL,"
    "dns2 TEXT NOT NULL,"
    "enabled TEXT NOT NULL"
    ");";

char* err_msg = nullptr;
rc = sqlite3_exec(db, create_table_sql, nullptr, nullptr, &err_msg);
if (rc != SQLITE_OK) {
    std::cerr << "SQL error: " << err_msg << std::endl;
    sqlite3_free(err_msg);
    sqlite3_close(db);
    return 1;
}

CROW_ROUTE(app, "/")
.methods("GET"_method,"POST"_method)
([]() {
    crow::response response{"Hello,world !"};
    response.set_header("Access-Control-Allow-Origin", "*");
    response.set_header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
    response.set_header("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With");
    response.set_header("Access-Control-Allow-Credentials", "true");
    return response;
});


CROW_ROUTE(app, "/ethernetdata")
.methods("GET"_method, "POST"_method)
([&db, &rc](const crow::request& req){
    json result;

    if (req.method == "GET"_method) {
        const char* sql = "SELECT * FROM ethernetdata;";
        char* err_msg = nullptr;
        rc = sqlite3_exec(db, sql, callback, &result, &err_msg);
        if (rc != SQLITE_OK) {
            std::cerr << "SQL error: " << err_msg << std::endl;
            sqlite3_free(err_msg);
        }

         crow::response response{result.dump()};
         response.set_header("Access-Control-Allow-Origin", "*");
         return response;
    } else if (req.method == "POST"_method) {
        // Parse the JSON data from the POST request
        json post_data = json::parse(req.body);

        // Modify the data in the database based on the POST request
        const char* update_sql = "UPDATE ethernetdata SET ip = ?, netmask = ?, router = ?, dns1 = ?, dns2 = ?, enabled = ? WHERE id = 1;";
        sqlite3_stmt* stmt;
        rc = sqlite3_prepare_v2(db, update_sql, -1, &stmt, nullptr);
        if (rc != SQLITE_OK) {
            std::cerr << "Cannot prepare statement: " << sqlite3_errmsg(db) << std::endl;
            sqlite3_finalize(stmt);
            return crow::response{500};
        }
    sqlite3_bind_text(stmt, 1, post_data["ip"].get<std::string>().c_str(), -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(stmt, 2, post_data["netmask"].get<std::string>().c_str(), -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(stmt, 3, post_data["router"].get<std::string>().c_str(), -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(stmt, 4, post_data["dns1"].get<std::string>().c_str(), -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(stmt, 5, post_data["dns2"].get<std::string>().c_str(), -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(stmt, 6, post_data["enabled"].get<std::string>().c_str(), -1, SQLITE_TRANSIENT);

    rc = sqlite3_step(stmt);
    if (rc != SQLITE_DONE) {
        std::cerr << "Cannot execute statement: " << sqlite3_errmsg(db) << std::endl;
        sqlite3_finalize(stmt);
        return crow::response{500};
    }

    // Populate the result object with the updated data
    const char* select_sql = "SELECT * FROM ethernetdata WHERE id = 1;";
    char* err_msg = nullptr;
    rc = sqlite3_exec(db, select_sql, callback, &result, &err_msg);
    if (rc != SQLITE_OK) {
        std::cerr << "SQL error: " << err_msg << std::endl;
        sqlite3_free(err_msg);
    }

    crow::response response{result.dump()};
    response.set_header("Access-Control-Allow-Origin", "*");
    response.set_header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
    response.set_header("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With");
    response.set_header("Access-Control-Allow-Credentials", "true");
    return response;

}

});

app.port(8000).multithreaded().run();
sqlite3_close(db);

return 0;
}

im trying to run http server as my backend to do crud request using c++ (library:Crow)

1

There are 1 best solutions below

1
Marcos Roberto Silva On

Please see in the link below an example of how you can enable CORS for your routes: (from Crow github repository)

https://github.com/CrowCpp/Crow/blob/master/examples/middlewares/example_cors.cpp

#include "crow.h"
#include "crow/middlewares/cors.h"

int main()
{
    // Enable CORS
    crow::App<crow::CORSHandler> app;

    // Customize CORS
    auto& cors = app.get_middleware<crow::CORSHandler>();

    // clang-format off
    cors
      .global()
        .headers("X-Custom-Header", "Upgrade-Insecure-Requests")
        .methods("POST"_method, "GET"_method)
      .prefix("/cors")
        .origin("example.com")
      .prefix("/nocors")
        .ignore();
    // clang-format on

    CROW_ROUTE(app, "/")
    ([]() {
        return "Check Access-Control-Allow-Methods header";
    });

    CROW_ROUTE(app, "/cors")
    ([]() {
        return "Check Access-Control-Allow-Origin header";
    });

    app.port(18080).run();

    return 0;
}