解決したいこと
LINE広告APIドキュメントにてPythonで書かれているサンプルコードを、GAS(JavaScript)で書き直して使いたい
開発の背景
- LINE広告のパフォーマンスレポートをスプレッドシートに自動で書き出したい
- 他プラットフォーム(GoogleやYahoo!)の広告データ抽出も行っていることもあり、GASで書きたい
発生しているエラー
{"errors":[{"reason":"Unauthorized","message":"JWT signature does not match locally computed signature. JWT validity cannot be asserted and should not be trusted."}]}
「JWT署名がローカルで計算された署名と一致しません。 JWTが有効である確証がないため、信頼すべきではありません」とのこと。
今動かしているソースコード
ドキュメントのPythonのコードを見て、自力でGASに翻訳してみたものが以下です。
サンプルコードは GET /v3/groups/{groupId}/children
を使っていたので、 GET /v3/adaccounts/{adaccountId}/campaigns
に変えています。
JavaScript
1function importAdsReport() { 2 const today = new Date(); 3 const access_key = "xxxxxxxxxxxx"; 4 const secretKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; 5 const accountId = "xxxxxxxxxxx"; 6 7 const header = `{"alg": "HS256", "kid": "${access_key}", "typ": "text/plain"}`; 8 9 const hex_digest = sha256(""); 10 const content_type = ""; 11 const payload_date = Utilities.formatDate(today, 'GMT', 'yyyyMMdd'); 12 const canonical_url = `/api/v3/adaccounts/${accountId}/campaigns`; 13 const payload = `${hex_digest}\n${content_type}\n${payload_date}\n${canonical_url}`; 14 15 const inputValue = `${base64(header)}.${base64(payload)}`; 16 const signature = hmacSha256(inputValue, secretKey); 17 const calculatedSignature = `${inputValue}.${signature}`; 18 19 const request_headers = { 20 "Date": Utilities.formatDate(today, 'GMT', 'E, dd MMM yyyy HH:mm:ss z'), 21 "Authorization": `Bearer ${calculatedSignature}` 22 } 23 24 const options = { 25 "method": "GET", 26 "headers": request_headers, 27 "muteHttpExceptions": true 28 }; 29 30 const response = UrlFetchApp.fetch('https://ads.line.me' + canonical_url, options); 31} 32 33/** 34 * base64エンコード 35 * @param {string} input - エンコードしたい文字列 36 * @return {string} - base64エンコードされた文字列 37 */ 38function base64(input) { 39 return Utilities.base64Encode(input, Utilities.Charset.UTF_8) 40} 41 42/** 43 * HMAC SHA 256でハッシュ化 44 * @param {string} text - ハッシュ化する文字列 45 * @param {string} key - ハッシュ化するシークレットキー 46 * @return {string} - ハッシュ値 47 */ 48function hmacSha256(text, key) { 49 const rowHash = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_256, text, key); 50 let txtHash = ''; 51 for (i = 0; i < rowHash.length; i++) { 52 let hashVal = rowHash[i]; 53 if (hashVal < 0) { 54 hashVal += 256; 55 } 56 if (hashVal.toString(16).length == 1) { 57 txtHash += '0'; 58 } 59 txtHash += hashVal.toString(16); 60 } 61 return txtHash; 62}; 63 64/** 65 * SHA 256でハッシュ化 66 * @param {string} input - ハッシュ化する文字列 67 * @return {string} - ハッシュ値 68 */ 69function sha256(input) { 70 const rawHash = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, input, Utilities.Charset.UTF_8); 71 let txtHash = ''; 72 for (i = 0; i < rawHash.length; i++) { 73 let hashVal = rawHash[i]; 74 if (hashVal < 0) { 75 hashVal += 256; 76 } 77 if (hashVal.toString(16).length == 1) { 78 txtHash += '0'; 79 } 80 txtHash += hashVal.toString(16); 81 } 82 return txtHash 83}
エラーの原因っぽいところ
signature
が間違っているんだろうと思っています。
HTTPリクエストに渡す calculatedSignature
は inputValue
と signature
から成っているのですが、 inputValue
はPythonで生成したものと一致していました。
Pythonのサンプルコードで
Python
1signature = hmac.new( 2 secret_key.encode(), 3 signing_input.encode(), 4 hashlib.sha256 5 ).digest()
のように書かれているところを、GASで
JavaScript
1const signature = hmacSha256(inputValue, secretKey);
としているのですが、このhmacSha256()
がよくないのかなと...。
今試していること
「要するにHS256形式での電子署名生成をGAS(JavaScript)でできればいいのでは」と思い、それらしき記事を見てみたりしているのですが、結局同じエラーが返ってきてしまっています…。
誤っている箇所がお分かりになる方いらっしゃいましたら、ご指摘いただけるととてもありがたいです…。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2022/09/12 14:34 編集
退会済みユーザー
2022/09/13 12:38
退会済みユーザー
2022/09/14 00:11 編集
退会済みユーザー
2022/09/13 13:26
退会済みユーザー
2022/09/19 03:40