Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crow Authorization Headers not working with CORs #806

Closed
code-snips opened this issue Apr 24, 2024 · 2 comments
Closed

Crow Authorization Headers not working with CORs #806

code-snips opened this issue Apr 24, 2024 · 2 comments

Comments

@code-snips
Copy link

code-snips commented Apr 24, 2024

Edit: using crow v1.1.0
I enable CORs in my Crow-Project to test the application with a vue application running on another port.
When Hosting the Vue-Build with crow, Authentication works.

When sending a POST Requst withAuthorization Headers OR data in the body, an OPTIONS and a POST Request are sent. both fail: OPTIONS (falis CORS Missing Allow Origin), POST (fails NS_ERROR_DOM_BAD_URI)
When sending the request without auth headers or body. the Post Resquests returns status 200.

axios.post(url) // works
axios.post(url, postData) // doesnt work
axios.post(url, {}, headers) // doesnt work

is this a configuration issue or a bug? the documentation states, OPTIONS route are handled automatically: https://crowcpp.org/master/guides/routes/#methods

Maybe this is the same issue as opened here: #721

My Code an Requests log:

cpp implementation

 crow::App<crow::CORSHandler> app;
auto &cors = app.get_middleware<crow::CORSHandler>();
origin = "*";
cors.global()
    .headers(
        "X-Custom-Header",
        "Upgrade-Insecure-Requests",
        "Accept",
        "Origin",
        "Content-Type",
        "Authorization",
        "Refresh",
        "Access-Control-Allow-Credentials")
    .allow_credentials()
    .methods(
        crow::HTTPMethod::GET,
        crow::HTTPMethod::POST,
        crow::HTTPMethod::OPTIONS,
        crow::HTTPMethod::HEAD,
        crow::HTTPMethod::PUT,
        crow::HTTPMethod::DELETE)
    .origin(origin);

    CROW_ROUTE(app, "/api/save")
        .methods(crow::HTTPMethod::POST)([this](const crow::request &req)
                                         {
        crow::response r();
        r.add_header("Content-Type", "application/json");
        return r;});

vuejs

    // // without auth, works
    const response = await axios.post('/api/save');

    // // with basic auth, CORS blocked
    const response = await axios.post('/api/save', {}, {
      auth: {
        username: "username",
        password: "password"
      }
    });

POST request with basic auth sends two requests, both fail.

first request

OPTIONS (falis CORS Missing Allow Origin)
scheme http
host localhost:8090
filename /api/save
Address 127.0.0.1:8090
Status
204
No Content
VersionHTTP/1.1
Transferred136 B (0 B size)
Referrer Policystrict-origin-when-cross-origin

Response Headers
HTTP/1.1 204 No Content
Allow: OPTIONS, HEAD, GET, POST
Content-Length: 0
Server: Crow/1.1.0
Date: Wed, 24 Apr 2024 08:09:52 GMT

Request Headers
OPTIONS /api/save HTTP/1.1
Host: localhost:8090
User-Agent: Mozilla/5.0
Accept: /
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Access-Control-Request-Method: POST
Access-Control-Request-Headers: authorization,content-type
Referer: http://localhost:3000/
Origin: http://localhost:3000
Connection: keep-alive
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site

second request

POST (fails NS_ERROR_DOM_BAD_URI)
scheme http
host localhost:8090
filename /api/save

Request Header
POST /api/save undefined
Host: localhost:8090
User-Agent: Mozilla/5.0
Accept: application/json, text/plain, /
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/json
Authorization: Basic YWRtaW46YWRtaW4=
Content-Length: 2
Origin: http://localhost:3000
Connection: keep-alive
Referer: http://localhost:3000/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site

POST request without auth

POST (status 200)
scheme http
host localhost:8090
filename /api/save

Response Header
HTTP/1.1 200 OK
Access-Control-Allow-Methods: GET, POST, OPTIONS, HEAD, PUT, DELETE
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: X-Custom-Header, Upgrade-Insecure-Requests, Accept, Origin, Content-Type, Authorization, Refresh, Access-Control-Allow-Credentials
Content-Type: application/json
Content-Length: 31
Server: Crow/1.1.0
Date: Wed, 24 Apr 2024 08:15:11 GMT
Connection: Keep-Alive

Request Header
POST /api/save HTTP/1.1
Host: localhost:8090
User-Agent: Mozilla/5.0
Accept: application/json, text/plain, /
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Origin: http://localhost:3000
Connection: keep-alive
Referer: http://localhost:3000/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
Content-Length: 0

@witcherofthorns
Copy link
Contributor

@code-snips hi, here is my code from my working backend server (Crow from master version):

cors.global()
    .origin("http://localhost:8080") // don't use *
    .allow_credentials()             // allow all credentials
    .headers(
        "Accept",
        "Origin",
        "Content-Type",
        "Authorization",
        "Refresh",
        "X-Requested-With"
    )
    .methods(
        crow::HTTPMethod::GET,
        crow::HTTPMethod::POST,
        crow::HTTPMethod::OPTIONS,
        crow::HTTPMethod::HEAD,
        crow::HTTPMethod::PUT,
        crow::HTTPMethod::DELETE
    )

I recommend not specifying "*" in the Origin header
I use axios in VueJs just like you, and it works:

export async function userUpdate(data){
    try {
        const { status: response } = await axios_api.put('/api/user', data);
        return response;
    }
    catch (error) {
        console.log(error);
    }
}

export async function userCreate(data){
    try {
        const { status: response } = await axios_api.post('/api/user', data);
        return response;
    }
    catch (error) {
        console.log(error);
    }
}

like this, for example, I return the user’s json and that’s it:

return response(OK, "application/json", user_json_string);

take a look at this example, I hope it helps you

@code-snips
Copy link
Author

thanks for your quick response @witcherofthorns . glad to hear someone is using the same tech stack.
i could resolve the problem with your cors configuration AND the library update from v1.1.0 to the 1.1.1 bugfix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants