[英]Google Api Service Account "error":"invalid_grant","error_description":"Invalid JWT Signature."
I am pretty new with google api, but I already spent 6 hours with this error.我对谷歌 api 很陌生,但我已经花了 6 个小时解决这个错误。 So I want to access my google drive files with a service account.所以我想使用服务帐户访问我的谷歌驱动器文件。 But I always get this error:但我总是得到这个错误:
{"error":"invalid_grant","error_description":"Invalid JWT Signature."} {“error”:“invalid_grant”,“error_description”:“JWT 签名无效。”}
This is the method I create and send the JWT in NodeJs:这是我在 NodeJs 中创建并发送 JWT 的方法:
const privateKeyFile = require("./user.json");
const base64url = require("base64url");
const jsonwebtoken = require("jsonwebtoken");
const querystring = require("querystring");
const request = require("request");
// HEADER
let header = { alg: "RS256", typ: "JWT" };
let encodedH = base64url(JSON.stringify(header));
// CLAIM SET
let exp = parseInt(Date.now() / 1000) + 60 * 20;
// issue time
let iat = parseInt(Date.now() / 1000);
let claimset = {
iss: "*********@*******.iam.gserviceaccount.com",
scope: "https://www.googleapis.com/auth/drive",
aud: "https://oauth2.googleapis.com/token",
exp: exp,
iat: iat,
};
let encodedCs = base64url(JSON.stringify(claimset));
// create signiture
let signitureBase = encodedH + "." + encodedCs;
jsonwebtoken.sign(
signitureBase,
privateKeyFile.private_key,
{
algorithm: "RS256",
header: header,
},
function (err, signature) {
request.post(
"https://oauth2.googleapis.com/token",
{
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: querystring.encode({
grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
assertion: signitureBase + "." + base64url(signature),
}),
},
function (error, response) {
console.log(error);
console.log(response);
}
);
}
);
Thanks in advance!提前致谢!
I believe your goal as follows.我相信你的目标如下。
For this, how about this answer?为此,这个答案怎么样?
In this pattern, crypto
and request
are used.在此模式中,使用了crypto
和request
。
const privateKeyFile = require("./user.json");
const cryptor = require("crypto");
const request = require("request");
const scopes = ["https://www.googleapis.com/auth/drive"];
const url = "https://www.googleapis.com/oauth2/v4/token";
const header = {
alg: "RS256",
typ: "JWT",
};
const now = Math.floor(Date.now() / 1000);
const claim = {
iss: privateKeyFile.client_email,
scope: scopes.join(" "),
aud: url,
exp: (now + 3600).toString(),
iat: now.toString(),
};
const signature =
Buffer.from(JSON.stringify(header)).toString("base64") +
"." +
Buffer.from(JSON.stringify(claim)).toString("base64");
var sign = cryptor.createSign("RSA-SHA256");
sign.update(signature);
const jwt = signature + "." + sign.sign(privateKeyFile.private_key, "base64");
request(
{
method: "post",
url: url,
body: JSON.stringify({
assertion: jwt,
grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
}),
},
(err, res, body) => {
if (err) {
console.log(err);
return;
}
console.log(body);
}
);
When you run the script, the following result is retrieved.运行脚本时,将检索到以下结果。
{
"access_token": "###",
"expires_in": ####,
"token_type": "Bearer"
}
In this pattern, googleapis
is used.在此模式中,使用了googleapis
。
const privateKeyFile = require("./user.json");
const { google } = require("googleapis");
let jwtClient = new google.auth.JWT(
privateKeyFile.client_email,
null,
privateKeyFile.private_key,
["https://www.googleapis.com/auth/drive"]
);
jwtClient.authorize((err) => {
if (err) console.log(err);
});
jwtClient.getRequestHeaders().then((auth) => {
console.log(auth);
});
When you run the script, the following result is retrieved.运行脚本时,将检索到以下结果。
{
"Authorization": "Bearer ###"
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.