I've written a very primitive C HTTP server and I want to support the JWT token using JWT-CPP. Basically, I have 2 endpoints:
- If the request is /auth/username, I will generate a JWT token with the username given in the URL.
- If the request is /verify, I will check the Cookie in the request header and look for a JWT token. If it exists, I will verify it and return the username in the JWT payload.
Here is the part of the code I send the response:
// Check and give JWT token
if (has_auth == 0 || auth_right == 0) {
// HTTPGET[1] contains the URL requested. For example, 'auth/username'
size_t pos1 = HTTPGET[1].find('/');
size_t pos2 = HTTPGET[1].find('/', pos1 1);
std::string mode = HTTPGET[1].substr(0, pos2);
printf("JWT: mode is: %s\n", mode.c_str());
if (strcmp(mode.c_str(), "/auth") == 0) {
printf("JWT: Auth\n");
size_t pos3 = HTTPGET[1].find('/', pos2 1);
std::string username = HTTPGET[1].substr(pos2 1, pos3);
printf("JWT: username is: %s\n", username.c_str());
auto token = jwt::create()
.set_issuer("auth0")
.set_type("JWS")
.set_payload_claim("sub", jwt::claim(username))
.set_issued_at(std::chrono::system_clock::now())
.set_expires_at(std::chrono::system_clock::now() std::chrono::seconds{86400})
.sign(jwt::algorithm::hs256{"secret"});
auto verifier = jwt::verify()
.allow_algorithm(jwt::algorithm::hs256{ "secret" })
.with_issuer("auth0");
auto decode = jwt::decode(token);
std::string GiveJWT = "HTTP/1.1 200 OK\r\nServer: myhttpserver\r\n" CORS_header "Content-type: text/plain\r\nSet-Cookie: token=" token
"\r\n\r\n JWT token generated successful!\nYour token's username is: " username "\n";
write(fd, GiveJWT.c_str(), GiveJWT.size());
return;
}
//return;
} else {
std::string NeedAuth = "HTTP/1.1 401 Unauthorized\r\nServer: myhttpserver\r\n" CORS_header "Content-type: text/plain\r\n\r\nAuthorization failed\n";
write(fd, NeedAuth.c_str(), NeedAuth.size());
}
// Verify user's token
// rel_path contains the url or subdomain of the request. For example, the url here should be './verify'.
if (strcmp(rel_path.c_str(), "./verify") == 0) {
printf("Get in the verify\n");
if (auth_right == 1) {
auto decode = jwt::decode(success_token);
std::string username = decode.get_payload_claim("sub").as_string();
printf("username is: %s\n", decode.get_payload_claim("sub").as_string());
std::string JWTConfirm = "HTTP/1.1 200 OK\r\nServer: myhttpserver\r\n" CORS_header "Content-type: text/plain\r\n\r\nYour user name is: ?" username "\n";
write(fd, JWTConfirm.c_str(), JWTConfirm.size());
return;
} else {
std::string JWTConfirm = "HTTP/1.1 401 Unauthorized\r\nServer: myhttpserver\r\n" CORS_header "Content-type: text/plain\r\n\r\nWhate are you looking at?";
write(fd, JWTConfirm.c_str(), JWTConfirm.size());
return;
}
}
This is the HTTP header & response I got from accessing /auth/oreo:

I can see the server is supporting CORS in its header, so the cookie should be able to transferred across domains. However, If I switch to the endpoint /verify, that token cookie will not be carried. I know Cookies are suppose to be session-based, but is there anyway I can carry this cookie as long as the browser session exist?
CodePudding user response:
Sorry for the misinterpretation ahead. What I meant was a different path, not different subdomains. In the end, I resolved this by adding the "Path=/" attribute after my Cookie, which allows the cookies to be carried forward across different paths.
However, If you have stored the old cookie before, make sure you clear them first. This could be my endpoint's issue, but if I don't clear the cookies, the request will mysteriously hang even after I close the socket on the server-side. I'm not sure why though.
