使用服务帐户和 OAuth 连接到 Google API
Connecting to Google API with Service Account and OAuth
我使用的环境本身不支持 GCP 客户端库。所以我想弄清楚如何使用手动制作的 JWT 令牌直接进行身份验证。
我已经调整了这里的任务使用 nodeJS 测试环境,用 jwa 来实现算法。
https://developers.google.com/identity/protocols/OAuth2ServiceAccount
私钥取自 JSON 版本的服务帐户文件。
当测试运行时,它会捕获一个非常基本的 400 错误,即 "invalid request"。我不确定如何解决它。
有人可以帮助确定我做错了什么吗?
var assert = require('assert');
const jwa = require('jwa');
const request = require('request-promise');
const pk = require('../auth/tradestate-2-tw').private_key;
const authEndpoint = 'https://www.googleapis.com/oauth2/v4/token';
describe('Connecting to Google API', function() {
it('should be able to get an auth token for Google Access', async () => {
assert(pk && pk.length, 'PK exists');
const header = { alg: "RS256", typ: "JWT" };
const body = {
"iss":"salesforce-treasury-wine@tradestate-2.iam.gserviceaccount.com",
"scope":"https://www.googleapis.com/auth/devstorage.readonly",
"aud":"https://www.googleapis.com/oauth2/v4/token",
"exp": new Date().getTime() + 3600 * 1000,
"iat": new Date().getTime()
};
console.log(JSON.stringify(body, null, 2));
const encodedHeader = Buffer.from(JSON.toString(header)).toString('base64')
const encodedBody = Buffer.from(JSON.toString(body)).toString('base64');
const cryptoString = `${encodedHeader}.${encodedBody}`;
const algo = jwa('RS256');
const signature = algo.sign(cryptoString, pk);
const jwt = `${encodedHeader}.${encodedBody}.${signature}`;
console.log('jwt', jwt);
const headers = {'Content-Type': 'application/x-www-form-urlencoded'};
const form = {
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
assertion: jwt
};
try {
const result = await request.post({url: authEndpoint, form, headers});
assert(result, 'Reached result');
console.log('Got result', JSON.stringify(result, null, 2));
} catch (err) {
console.log(JSON.stringify(err, null, 2));
throw (err);
}
});
});
使用 JSON.stringify 而不是 JSON.toString。来自您问题中的 link:
{"alg":"RS256","typ":"JWT"}
The Base64url representation of this is as follows:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9
当使用 JSON.toString() 然后使用 base64 编码时,您会得到 W29iamVjdCBKU09OXQ== 这说明 400 是无效请求,因为它无法解密您发送的任何内容。
我使用的环境本身不支持 GCP 客户端库。所以我想弄清楚如何使用手动制作的 JWT 令牌直接进行身份验证。
我已经调整了这里的任务使用 nodeJS 测试环境,用 jwa 来实现算法。
https://developers.google.com/identity/protocols/OAuth2ServiceAccount
私钥取自 JSON 版本的服务帐户文件。
当测试运行时,它会捕获一个非常基本的 400 错误,即 "invalid request"。我不确定如何解决它。
有人可以帮助确定我做错了什么吗?
var assert = require('assert');
const jwa = require('jwa');
const request = require('request-promise');
const pk = require('../auth/tradestate-2-tw').private_key;
const authEndpoint = 'https://www.googleapis.com/oauth2/v4/token';
describe('Connecting to Google API', function() {
it('should be able to get an auth token for Google Access', async () => {
assert(pk && pk.length, 'PK exists');
const header = { alg: "RS256", typ: "JWT" };
const body = {
"iss":"salesforce-treasury-wine@tradestate-2.iam.gserviceaccount.com",
"scope":"https://www.googleapis.com/auth/devstorage.readonly",
"aud":"https://www.googleapis.com/oauth2/v4/token",
"exp": new Date().getTime() + 3600 * 1000,
"iat": new Date().getTime()
};
console.log(JSON.stringify(body, null, 2));
const encodedHeader = Buffer.from(JSON.toString(header)).toString('base64')
const encodedBody = Buffer.from(JSON.toString(body)).toString('base64');
const cryptoString = `${encodedHeader}.${encodedBody}`;
const algo = jwa('RS256');
const signature = algo.sign(cryptoString, pk);
const jwt = `${encodedHeader}.${encodedBody}.${signature}`;
console.log('jwt', jwt);
const headers = {'Content-Type': 'application/x-www-form-urlencoded'};
const form = {
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
assertion: jwt
};
try {
const result = await request.post({url: authEndpoint, form, headers});
assert(result, 'Reached result');
console.log('Got result', JSON.stringify(result, null, 2));
} catch (err) {
console.log(JSON.stringify(err, null, 2));
throw (err);
}
});
});
使用 JSON.stringify 而不是 JSON.toString。来自您问题中的 link:
{"alg":"RS256","typ":"JWT"}
The Base64url representation of this is as follows:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9
当使用 JSON.toString() 然后使用 base64 编码时,您会得到 W29iamVjdCBKU09OXQ== 这说明 400 是无效请求,因为它无法解密您发送的任何内容。