0

nodejsを使用してサービスアカウントのoauth2トークンを取得しようとしています。私はのための要求を行うとき、それは期待するものの大まかなアイデアを得るためにHTTP /残りのドキュメントで見てきたノードの例がありませんがNodejsがサービスアカウントのoauth2トークンを取得する要求を投稿しました

https://developers.google.com/identity/protocols/OAuth2ServiceAccount#makingrequest

:私はここで見つけるドキュメントを以下のよトークンしかし、私が返信している応答は:

無効なJWT署名です。

署名を計算する際の一般的な概要として、headerとclaimのbase64urlでエンコードされた値をとり、sha256とGoogle開発者コンソールの秘密鍵でハッシュし、その値をbase64urlでエンコードします。

だから私のヘッダーは次のとおりです。

var header = {"alg":"RS256","typ":"JWT"} 
    var encodedHeader = base64url(new Buffer(header).toString('utf8')); 

上記のドキュメントでもこの値は、それをコードするbase64url後がどうなるかを示しています

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9 

そしてI出力、私のencodedHeader値:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9 

いいです。それは一致します。他の値には64バーリのエンコーディングの問題はありません。次はクレームです:

var claim ={"aud":"https://www.googleapis.com/oauth2/v4/token","scope":"https://www.googleapis.com/auth/gmail.send","iss":"*****censoredvalue*****gserviceaccount.com","exp":1505399833,"iat":1505396233} 

同じプロセスを経てエンコードされます(セキュリティ上の理由から表示できません)。私はテスト目的のために署名を計算するためにサードパーティのサイトを使用していますが、入力がencodedHeader.encodedClaim +プライベートキー(値されている瞬間のために

var encodedClaim = base64url(new Buffer(claim).toString('utf8')); 

:----- PRIVATE KEYをBEGIN .... SHA256を使用しています。私はその出力を受け取り、それをエンコードします。

私は今、私は次のようにトークンエンドポイントへのリクエストを行いますencodedHeader.encodedClaim.encodedSignature

var encoded_jwt = encodedHeader + '.' + encodedClaim + '.' + encodedSignature; 

であるJWTを持っている:

// Set the headers 
    var headers = { 
     'HTTP-Version': 'HTTP/1.1', 
     'Content-Type': 'application/x-www-form-urlencoded' 
    } 

    var bodyOptions = { 'grant_type': "urn:ietf:params:oauth:grant-type:jwt-bearer", assertion: encoded_jwt } 

    // Configure the request 
    var options = { 
     url: 'https://www.googleapis.com/oauth2/v4/token', 
     method: 'POST', 
     headers: headers, 
     form: bodyOptions, 
     json: true 
    } 

    // Start the request 
    request(options, function (error, response, body) { 
     if (!error && response.statusCode == 200) { 
      // Print out the response body 
      console.log(body) 
     } 
     else{ 
      context.log(error); 
      context.log(response); 
     } 
    }); 

そして、私が取得する場所これは無効な署名があるというエラーの応答。

なぜそれが無効な署名であるかに関するアイデア。私はまた、それが特定のものではないことを確かめるためにいくつかの署名生成サイトを試しましたが、それは常に同じエラーです。 JWSを計算するために

答えて

0

は、次のようなcrypto moduleを使用することができます。

datagoogle-oauth-libraryテストケースから取り出した完全な例 encodedHeader + '.' + encodedClaim

ある

const privateKey = fs.readFileSync('private.pem', 'utf-8'); 

const signer = crypto.createSign('sha256'); 
signer.update(data); 
const signature = signer.sign(privateKey, 'base64'); 

"use strict"; 

const crypto = require('crypto'); 
const fs = require('fs'); 

const publicKey = fs.readFileSync('public.pem', 'utf-8'); 
const privateKey = fs.readFileSync('private.pem', 'utf-8'); 

const maxLifetimeSecs = 86400; 
const now = new Date().getTime()/1000; 
const expiry = now + (maxLifetimeSecs/2); 

const idToken = '{' + 
    '"iss":"testissuer",' + 
    '"aud":"testaudience",' + 
    '"azp":"testauthorisedparty",' + 
    '"email_verified":"true",' + 
    '"id":"123456789",' + 
    '"sub":"123456789",' + 
    '"email":"[email protected]",' + 
    '"iat":' + now + ',' + 
    '"exp":' + expiry + '}'; 

const envelope = '{' + 
    '"kid":"keyid",' + 
    '"alg":"RS256"' + 
    '}'; 

let data = new Buffer(envelope).toString('base64') + '.' + 
    new Buffer(idToken).toString('base64'); 

const signer = crypto.createSign('sha256'); 
signer.update(data); 
const signature = signer.sign(privateKey, 'base64'); 

data += '.' + signature; 

console.log(data); 
関連する問題