前提・実現したいこと
Kintoneのような、Javascriptで機能拡張が可能なWEBデータベースアプリを使用しています。
このアプリ上に、クラウドストレージのBOX
https://www.box.com/ja-jp/home
のAPI機能を使い、UI を表示させたいのですが、API連携に必要なアクセストークンの取得でつまづいています。
処理は全てクライアントのブラウザ上で行われます。非推奨なのは分かっています。
完了したいプロセス
https://ja.developer.box.com/guides/authentication/jwt/without-sdk/
Node.js及びそのライブラリ群やSDKは使用できませんので、下記ライブラリを使用しています。
axios.min.js ($ajaxでもPOST出来ますが、なるべくサンプルの記述に合わせたかったため)
https://github.com/axios/axios
jsrsasign-all-min.js (https://jwt.io/ のライブラリより)
https://github.com/kjur/jsrsasign
querystring.js (ネット上で拾ってきました)
発生している問題・エラーメッセージ
ボタンを押すと、UI表示の関数が実行され、その関数の中で、下記getBoxAccessToken()が実行される形となっています。
assertionをPOSTするとエラーが返ります。
assertionを https://jwt.io/ でデバッグすると、signature invalidとなるので、署名が成功していないのですが、原因がどこにあるかわかりません。
POST https://api.box.com/oauth2/token 400 error: "invalid_request" error_description: "Invalid grant_type parameter or parameter missing"
該当のソースコード
JavaScript
1/* getBoxConfig()で取得するconfigの中身 2{ 3 "boxAppSettings": { 4 "clientID": CLIENT_ID, 5 "clientSecret": CLIENT_SECRET, 6 "appAuth": { 7 "publicKeyID": PUBLICK_KEY_ID, 8 "privateKey": "-----BEGIN ENCRYPTED PRIVATE KEY-----\n...\n-----END ENCRYPTED PRIVATE KEY-----\n", 9 "passphrase": PASS_PHRASE 10 } 11 }, 12 "enterpriseID": ENTERPRISE_ID 13} 14*/ 15 16const getBoxAccessToken = async () => { 17 18 // 読取専用のレコードからコンフィグ情報(JSON)を読み取る 19 let config = await getBoxConfig(); 20 config = JSON.parse(config.Response.Data[0].Body); 21 console.log(config); 22 23 if (!config) { 24 alert('BOX API コンフィグ情報の取得に失敗しました'); 25 return; 26 } 27 28 // 秘密キーをパスコードを使って複合化 29 let prvKey = KEYUTIL.getKey(config.boxAppSettings.appAuth.privateKey, config.boxAppSettings.appAuth.passphrase); 30 31 32 // 認証用URLの定数宣言 33 const authenticationUrl = "https://api.box.com/oauth2/token"; 34 35 // ペイロードを宣言 36 let oPayload = {}; 37 oPayload.iss = config.boxAppSettings.clientID; 38 oPayload.sub = config.enterpriseID; 39 oPayload.box_sub_type = 'enterprise'; 40 oPayload.aud = authenticationUrl; 41 oPayload.jti = KJUR.crypto.Util.getRandomHexOfNbytes(64); 42 oPayload.exp = Math.floor(Date.now() / 1000) + 45; 43 44 let sPayload = JSON.stringify(oPayload); 45 console.log(sPayload); 46 47 // 公開キーIDを格納(使用しない?) 48 let keyId = config.boxAppSettings.appAuth.publicKeyID; 49 50 // ヘッダーを宣言 51 let oHeader = { 52 alg: 'RS256', 53 typ: 'JWT', 54 keyid: keyId 55 } 56 57 let sHeader = JSON.stringify(oHeader); 58 console.log(sHeader); 59 60 // ヘッダー、ペイロードをキー情報を使って署名 61 var assertion = KJUR.jws.JWS.sign('RS256', sHeader, sPayload, prvKey); 62 console.log(assertion); 63 console.log(KJUR.jws.JWS.parse(assertion)); 64 65 // クエリ文字列作成用のオブジェクト宣言 66 let obj = { 67 grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer', 68 assertion: assertion, 69 client_id: config.boxAppSettings.clientID, 70 client_secret: config.boxAppSettings.clientSecret 71 } 72 73 // クエリ文字列変換ライブラリを使用してクエリ文字列を生成 74 const query = serialize(obj); 75 console.log(query); 76 /* queryの内容 77 ?grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=ASSERTION&client_id=CLIENT_ID&client_secret=CLIENT_SECRET 78 */ 79 80 81 // axiosライブラリで認証用URLとクエリ文字列をPOST 82 let accessToken = await axios.post( 83 authenticationUrl, 84 query 85 ).then(response => response.data.access_token); 86 87 console.log(accessToken); 88 return accessToken; 89 90 /* BOX のコードサンプル 91 return accessToken = await axios.post( 92 authenticationUrl, 93 querystring.stringify({ 94 grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer', 95 assertion: assertion, 96 client_id: config.boxAppSettings.clientID, 97 client_secret: config.boxAppSettings.clientSecret 98 }) 99 ) 100 .then(response => response.data.access_token) 101 */ 102}
試したこと
https://support.box.com/hc/ja/articles/360044192233-API-Salesforce-SDK-Invalid-Crypto-Key-%E7%84%A1%E5%8A%B9%E3%81%AA%E6%9A%97%E5%8F%B7%E9%8D%B5-
を参考に、秘密キーをopenSSLで復号化※し、それをKJUR.jws.JWS.signに渡す
※-----BEGIN PRIVATE KEY-----で始まるもの
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。