Chrome 不跨不同子域保存 Cookie
Chrome not saving Cookies across different subdomains
我编写了一个非常原始的 C++ HTTP 服务器,我想使用 JWT-CPP 支持 JWT 令牌。基本上,我有 2 个端点:
- 如果请求是 /auth/username,我将使用 URL 中给定的用户名生成一个 JWT 令牌。
- 如果请求是 /verify,我会检查请求中的 Cookie header 并查找 JWT 令牌。如果它存在,我将验证它和 return JWT 负载中的用户名。
这是我发送响应的部分代码:
// 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;
}
}
这是我从访问 /auth/oreo 得到的 HTTP header 和响应:
我可以看到服务器在其 header 中支持 CORS,因此 cookie 应该能够跨域传输。但是,如果我切换到端点 /verify,则不会携带该令牌 cookie。我知道 Cookie 应该是 session-based,但是只要浏览器 session 存在,无论如何我可以携带这个 cookie 吗?
对于前面的误解,我们深表歉意。我的意思是不同的路径,而不是不同的子域。最后,我通过在我的 Cookie 后面添加“Path=/”属性解决了这个问题,它允许 cookie 跨不同的路径转发。
但是,如果您之前存储过旧的 cookie,请务必先清除它们。这可能是我端点的问题,但如果我不清除 cookie,即使在我关闭服务器端的套接字后,请求也会神秘地挂起。我不确定为什么。
我编写了一个非常原始的 C++ HTTP 服务器,我想使用 JWT-CPP 支持 JWT 令牌。基本上,我有 2 个端点:
- 如果请求是 /auth/username,我将使用 URL 中给定的用户名生成一个 JWT 令牌。
- 如果请求是 /verify,我会检查请求中的 Cookie header 并查找 JWT 令牌。如果它存在,我将验证它和 return JWT 负载中的用户名。
这是我发送响应的部分代码:
// 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;
}
}
这是我从访问 /auth/oreo 得到的 HTTP header 和响应:
我可以看到服务器在其 header 中支持 CORS,因此 cookie 应该能够跨域传输。但是,如果我切换到端点 /verify,则不会携带该令牌 cookie。我知道 Cookie 应该是 session-based,但是只要浏览器 session 存在,无论如何我可以携带这个 cookie 吗?
对于前面的误解,我们深表歉意。我的意思是不同的路径,而不是不同的子域。最后,我通过在我的 Cookie 后面添加“Path=/”属性解决了这个问题,它允许 cookie 跨不同的路径转发。
但是,如果您之前存储过旧的 cookie,请务必先清除它们。这可能是我端点的问题,但如果我不清除 cookie,即使在我关闭服务器端的套接字后,请求也会神秘地挂起。我不确定为什么。