[ERROR] In the error handler looking for a 401, and have a 401 [ERROR] Handleing the 401 error...
とかエラーが出てしまい動きません…
force.comからOAuth2で取得したaccess tokenには有効期限があるのでrefresh tokenを使って再度取得する必要があるのですが…そこが動作していないようです。
※force.comのOAuthについて詳しくはこちらで
エラーのコールバックも呼んでくれないので有効期限切れたかどうかも検出できず…
なんとかhackできないかと、こんな感じでモジュールの中身をダンプしてみます。
var FDC = require('com.salesforce'); for (var i in FDC.ForceOAuth) { Ti.API.debug(i + ':' + FDC.ForceOAuth[i]); }
最終的にREST APIの呼び出しはここに来るようです。
[DEBUG] makeRestCall:function (path, callback, error, method, payload, retry) {var restUrl=Ti.Network.decodeURIComponent(fa.instanceUrl)+'/services/data'+path;var xhr=Ti.Network.createHTTPClient();xhr.onload=function(){Ti.API.info("REST Response: "+this.responseText);var data="";if(this.responseText){data=this.responseText;} callback(data);};xhr.onerror=function(e){Ti.API.error("XHR, error handler..."+"\nDbDotCom.REST.OAuth.refreshToken: "+fa.refreshToken+"\nretry: "+retry+"\n e: "+e.error+"\nXHR status: "+this.status);if(!fa.refreshToken||retry){error(e.error);}else{Ti.API.error("In the error handler looking for a 401, and have a "+xhr.status);if(xhr.status===401){Ti.API.error("Handleing the 401 error...");exports.refreshAccessToken(function(oauthResponse){Ti.API.error("Refresh response... "+oauthResponse);fa.makeRestCall(path,callback,error,method,payload,true);},error);}else{Ti.API.error("Not a 401 error, re-throwing...");error(e);}}};if(fa.usePostBin===true){restUrl="http://www.postbin.org/135onm5";} xhr.open(method||"GET",restUrl,true) Ti.API.info("Rest url: "+restUrl);xhr.setRequestHeader("Authorization","OAuth "+Ti.Network.decodeURIComponent(fa.accessToken));xhr.setRequestHeader("Content-Type","application/json");xhr.send(payload);}
出てるログから、exports.refreshAccessToken()の呼び出しの中でエラーが起きてコールバックまで戻って来ないようです。
ダンプしたソースを参考に、こんな感じでhackしてみました。
※モジュール内で定義されてるobjectのプロパティは動的に書き換えられない?&スコープ的にアクセスできない変数があったので結構無理矢理
使い方は、requireした後にこのファイルをincludeしてパッチを当て、ForceOAuthの代わりにForceOAuth2を使うようにします。ForceOAuth2.openのパラメータにはclient id
var FDC = require('com.salesforce'); Ti.include('fdc-patch.js'); FDC.ForceOAuth2.open('CLIENT_ID');
パッチしたポイントは2つ。refreshAccessTokenを
Winter '12でリリースされたApex RESTを使って公開したAPIのURLは、$instance_url/services/apexrest/... となるので、FDC.ForceOAuth2.makeRestCall('/apexrest/myapi', callback) の様な感じで使える様になります。
marketplaceのモジュールのページには、"This toolkit is maintained by the community and sponsored by salesforce.com. Salesforce.com does not officially support this product."とか書いてあるんですが、パッチとか提供したい場合どこに連絡すればいいんでしょうか… githubとかにソース上がってればforkするのに…
この記事はForce.com Advent Calendar 2011に参加しています。
恐れ入ります。
返信削除有益な情報をありがとうございます。
私も同じモジュールを入れて動かしています。
やはり時間が経つと認証でコケてしまいました。
そこでpomuさんのパッチを当てたところ、
ログイン画面にリダイレクトされる前に
Script Error = Result of expression 'oauthJ' [null] is not an object. at fdc-patch.js (line 12).
を吐くようになりました。
パッチの当て方が正しければ、
10行目のTi.App.Properties.getString("oauthData_preference");は
nullにはならないという認識でよいのでしょうか...?
恐らく本来ならばFDCで何かしらの値がセットされてこの処理に入るということですよね...
"oauthData_preference"は認証時にモジュール内部で格納されるのですが、初回の認証前だとnullでエラーになってしまいますね…
返信削除ちょっと修正しました。
ちなみに、OAuth認証の情報をアプリから削除する方法が用意されていませんが、"oauthData_preference"の有無でOAuthのログイン画面に飛ばすかを判断している様なので、Ti.App.Properties.removeProperty("oauthData_preference");してやるとログイン画面が出る様に戻ります。
返信削除なんとおお(; ・`д・´)
返信削除さっそくのアップデート有り難うございます。
さらに戻りの方法まで教えて頂いてしまって恐縮です。
さっそく週明けに試してきます!
有益な情報をありがとうございます。
返信削除pomuさんのパッチを当てたところ、
[ERROR] XHR, error handler...
DbDotCom.REST.OAuth.refreshToken: 5Aep861rEpScxnNE64xeqQ1jBsxOFB2rIxGXSMrNbE68PJhzSB0zvba.nZLWR8w94ol5KE07GwanA%3D%3D
retry: undefined
e: undefined
XHR status: 400
[ERROR] In the error handler looking for a 401, and have a 400
[ERROR] Not a 401 error, re-throwing...
エラーになりましたが、
githubから見ると
FDC.ForceOAuth2.makeRestCall('/data/v22.0/query/?...', function(e) {...});
メソッドがあります。申し訳ございませんが、具体的にどうのように使えば良いのか
教えられて頂きませんか?
宜しくお願いします。
access tokenの期限が切れた時にログにはそのエラー残ります。
削除また、refresh時のsecretは要らない様に仕様が変わっていましたので、secret渡さなくても良くなってます。