VSCode 拡張機能開発で OAuth 認証 - 3 <終>
最終的にこんな形になりました。Promise ベースで Http リクエストを送れるrequest-promise
モジュールを新たに導入しました。
startOAuth = async () => { const oauth = new OAuth.OAuth(...); //RequestTokenの取得 oauth.getOAuthRequestToken({ 'scope': ... }, async (err, request_token, request_token_secret, results) => { if (err !== null){ console.log(err); } else { //はてなログイン処理 this.getRK() .then((rk) => { //許可ボタン押下のためrkmを取得 return this.getRKM(request_token, rk as string); }) .then((arr) => { ... //verifierを取得。arr = {'rk': rk, 'rkm': rkm}が格納 return this.getVerifier(request_token, arr.rk, arr.rkm); }) .then((verifier) => { ... //AccessTokenを取得 oauth.getOAuthAccessToken(..., (...) => { ... console.log(">>>Congraturations!!<<<"); console.log('AccessToken: ' + accessToken); console.log('AccessTokenSecret: ' + accessTokenSecret); console.log('ParsedQueryString: ' + parsedQueryString); }); }) .catch((err) => { console.log(err); }); } };
Promise チェーンを作って非同期処理を順次実行するようにしました。
oauth.getOAuthRequestToken
及びoauth.getOAuthAccessToken
はコールバックで値を返すため、返り値がvoid
です。
どうにか Promise チェーンに絡めたかったのですが、諦めてコールバック形式にしました。
以下各ステップのメソッド実装。なおrp
はrequest-promise
モジュールのインスタンスです。
import * as rp from 'request-promise'; //はてなログイン処理 private getRK = async () => { //ヘッダーを定義 const headers = {'Content-Type':'application/json'}; //オプションを定義 const loginOptions = { url: api.LOGIN_URL, method: 'POST', headers: headers, json: true, form: this.user, resolveWithFullResponse: true }; return await rp(loginOptions) .then((response) => { const cookie = response.headers['set-cookie']; if (cookie !== undefined){ const _rk = (cookie as string[])[5].match("(rk=.*); domain"); if (_rk !== null){ const rk = _rk[1]; console.log('rk: ' + rk); return rk; } } else { return null; } }); } //許可ボタン押下のためrkm取得 private getRKM = async (requestToken: string, rk: string) => { const reqTokenOptions = { url: api.RES_OWNER_AUTH_URL, qs: { oauth_token: requestToken }, method: 'GET', headers: { cookie: rk } }; return await rp(reqTokenOptions) .then((response) => { const _rkm = response.match("name=\"rkm\" value=\"(.*)\""); if (_rkm !== null){ const rkm = _rkm[1]; console.log('rkm: ' + rkm); return {'rk': rk, 'rkm': rkm as string}; } else { return null; } }); } //verifier取得 private getVerifier = async (requestToken: string, rk: string, rkm: string) => { const verifierOptions = { url: api.RES_OWNER_AUTH_URL, qs: { oauth_token: requestToken, rkm: rkm }, method: 'POST', headers: { cookie: rk } }; return await rp(verifierOptions) .then((response) => { const _verifier = response.match("<div class=verifier><pre>(.*)</pre></div>"); if (_verifier !== null){ const verifier = _verifier[1]; console.log('verifier: ' + verifier); return verifier as string; } else { return null; } }); }
ひとつ注意点ですが、getRKM
の返り値は{'rk': rk, 'rkm': rkm as string}
となっています。
これは次のgetVerifier
において、rk
とrkm
の2つの値が必要となるためです。
まあまあいい形に収まったと思いますので、本連載はこれで終了とします。次は API を叩く実装か Kotlin ネタに戻るか……。