我仍然收到来自 google 的“invalig_grant:/。我放弃了。
我正在使用 C++ 中的服务帐户与 googleapi 日历进行交互(使用 curl)。 有一个代码:
调用登录函数:
loginService(
"XXXXXXXXXXXXXXXXXXXXXXX@developer.gserviceaccount.com",
"XXXXXXXXXXXXXX@gmail.com",
"key.p12"
);
有登录功能:
int loginService(const string &client_id,const string &user_id,const string &key_path){
Json::FastWriter writer;
Json::Value header;
header["alg"] = "RS256";
header["typ"] = "JWT";
string JWT_header = writer.write(header);
Json::Value claim;
int iat_time=time(NULL);
int exp_time = iat_time+3600;
claim["iss"] = client_id;
claim["scope"] = _api_url+"auth/calendar";
claim["sub"] = user_id;
claim["aud"] = "https://accounts.google.com/o/oauth2/token";
claim["exp"] = exp_time;
claim["iat"] = iat_time;
string JWT_claimSet = writer.write(claim);
JWT_header = base64_encode(JWT_header);
JWT_claimSet = base64_encode(JWT_claimSet);
if (JWT_header.find("=")!=string::npos) JWT_header.erase(JWT_header.find("="));
if (JWT_claimSet.find("=")!=string::npos) JWT_claimSet.erase(JWT_claimSet.find("="));
string signature = JWT_header+"."+JWT_claimSet;
string JWT_signature = signWithRsaSha256(signature,key_path);
JWT_signature = base64_encode(JWT_signature);
if (JWT_signature.find("=")!=string::npos) JWT_signature.erase(JWT_signature.find("="));
string assertion = JWT_header + "." + JWT_claimSet + "." + JWT_signature;
string post_data = "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=" + assertion;
curlPost("https://accounts.google.com/o/oauth2/token", post_data);
Json::Reader reader;
Json::Value data;
bool parsingSuccessful = reader.parse(_read_data, data);
return 0;
}
有散列函数:
string signWithRsaSha256(const string &input, const string &privateKey)
{
FILE *fp;
EVP_PKEY *pkey = 0;
EVP_MD_CTX *ctx = 0;
const EVP_MD *sha256Md = 0;
unsigned char sig[256];
unsigned int s(0);
PKCS12 *p12 = 0;
X509 *cert= 0;
string out;
OpenSSL_add_all_ciphers();
OpenSSL_add_all_digests();
OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();
ctx = EVP_MD_CTX_create();
EVP_MD_CTX_init(ctx);
sha256Md = EVP_sha256();
try {
EVP_SignInit(ctx, sha256Md);
EVP_SignUpdate(ctx, input.c_str(), input.size());
ERR_load_crypto_strings();
if (!(fp = fopen(privateKey.c_str(), "rb"))) {
cerr << "Error opening file "<< privateKey;
}
p12 = d2i_PKCS12_fp(fp, NULL);
fclose (fp);
if (!p12) {
cerr << "Error reading PKCS#12 file\n";
}
if (!PKCS12_parse(p12, "notasecret", &pkey, &cert, NULL)) {
cerr << "Error parsing PKCS#12 file\n";
}
s = EVP_PKEY_size(pkey);
EVP_SignFinal(ctx, sig, &s, pkey);
out=(char*)sig;
}
catch (const char *s)
{
cerr << "ERROR: RSA SHA256 hashing failed: " <<s<< endl;
}
PKCS12_free(p12);
EVP_MD_CTX_destroy(ctx);
X509_free(cert);
EVP_cleanup();
return out;
}
和发布功能:
int curlPost(const string &url, const string &post_data)
{
_curl_handle = curl_easy_init();
curl_easy_setopt(_curl_handle, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(_curl_handle, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(_curl_handle, CURLOPT_USERAGENT, MY_USER_AGENT);
curl_easy_setopt(_curl_handle, CURLOPT_WRITEFUNCTION, WriteFunction);
curl_easy_setopt(_curl_handle, CURLOPT_WRITEDATA, &_read_data);
curl_easy_setopt(_curl_handle, CURLOPT_WRITEHEADER, &_read_header);
curl_easy_setopt(_curl_handle, CURLOPT_URL, url.c_str());
curl_easy_setopt(_curl_handle, CURLOPT_POST, 1);
curl_easy_setopt(_curl_handle, CURLOPT_POSTFIELDS, post_data.c_str());
_curl_result = curl_easy_perform(_curl_handle);
curl_easy_cleanup(_curl_handle);
return 0;
}
最佳答案
让 JWT 运行起来有点棘手(尤其是在 c/c++ 中)。从编码、签名 alg、json 格式或者即使您的本地系统时钟不是 NTP 时间同步的任何内容都可能导致通用 invalid_grant
但是,请查看以下内容是否 link有帮助。
(我想晚发总比不发好)
关于c++ - "invalid_grant"- 通过 C++ 中的 Google 服务帐户与 googleapi 日历交互,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25283955/