OAuth 2.0 User-Agent Flowを使ってサーバレスでSalesforceにアクセスする

もはや自分はブログほとんど更新しておらず、最近はゆるいことをTwitterでのみやってる感が強いですが、ネタ的にこれは自分が書いとくべきとおもったネタに関してはこのブログで書いておくことにしています。今回もそれです。


Salesforce の Winter '11 で、OAuth 2.0へ対応(Draft 10相当)されたわけだけど(OAuth 1.0a への対応はすでに去年の秋にしている)、この中にはUser-Agent Flowという方式への対応もなされている。これはJavaScriptFlashなどのWebページ埋め込みのスクリプトからOAuth認証を受けるためのフロー。

つまり、これを利用すると、Facebook ConnectTwitter @Anywhereなどと同じように、任意のWebページからSalesforceAPIに対して直接、サーバの介在なしで接続できるようになる。

SalesforceのOAuth 2.0 User-Agent Flowへの対応についてはこちら

OAuth2 利用のフロー

コンシューマ登録(リモートアクセスの作成)

SalesforceにおけるOAuthのコンシューマ登録は、管理設定画面の中から「アプリケーションの設定」>「開発」>「リモートアクセス」のメニューより新規に登録できる。

トークンの取得(リクエスト)

次に、HTMLページを作成し、前のステップで作成したコールバックのHTMLファイルと同じドメインに配置する。この中でOAuthでの承認を行うアクションを記述する。

具体的には、Salesforceの提供するAuthorization Endpointに対して、事前のコンシューマ登録の際に生成されたConsumer Keyをclient_idとし、承認後にコールバックされるURIをredirect_uriとしてパラメータにくっつけた上でブラウザを同エンドポイントに対してリダイレクト(あるいはWindowをポップアップ)する。

URLは以下のような形になる。

https://login.salesforce.com/services/oauth2/authorize?response_type=token&client_id=3MVG9lKcPoNINVBIPJjdw1J9LLJbP_pqwoJYyuisjQhr_LLurNDv7AgQvDTZwCoZuDZrXcPCmBv4o.8ds.5iE&redirect_uri=https%3A%2F%2Fwww.mysite.com%2Fuser_callback.jsp&state=mystate

リダイレクトされた画面上でSalesforceはログインおよび承認画面を表示し、アクセス許可してよいかをプロンプトする。

トークンの取得(レスポンス)

ユーザがアプリによるアクセスを承認した場合、コールバック先のURLに対してWebブラウザをリダイレクトする。その際、トークン値は以下のような形でFragment Identifier内に渡される。

https://www.mysite.com/user_callback.jsp#access_token=00Dx00000008mib%21AQIAQL34fBVczu13lJBiDAlX3Vqg9Fgna3ad8wvu_mUGXRyN5syhxyOOktu4wGx2gavlSXPC5Y4D594l1RLV1dCUDGqCAmNr&instance_url=https%3A%2F%2Fna1.salesforce.com&id=https%3A%2F%2Flogin.salesforce.com%2Fid%2F00Dx00000008mib%2F005x0000000I8It&issued_at=1286646354574&signature=HKMw6%2FV2Hem%2FXulGvvSm80J94tJ1DScsLAUar1T32cc%3D&state=mystate

これにより、WebページのリダイレクトだけでAccessTokenをGETできる。ここまではOAuth 2.0 User-Agent Flowと同じ(なんか微妙にちょっと違うかもしれんけどまあいいや)。

API呼び出し

いままでSalesforceAPIでは、API認証に独自のSessionIDという値を利用していた。そして以前のOAuth 1.0aの際は、AccessTokenからこのSessionIDに変換するリクエストを余分に行う必要があったが、今度からこの値にOAuthのAccessTokenを利用できるようになった。なので、以下のようにそのままSessionIDの値にセットすればよい。

sforce.connection.sessionId = accessToken;

これでセッションIDを利用して認証された状態でAPIリクエストを送ることができるわけだが、しかし通常Webページでは異なるドメインからリクエストを送ることができないため、いろいろ工夫しなければAPI Endpointにアクセスできない。

Flashの世界では、crossdomain.xmlというポリシーファイルによって、クロスドメインのアクセスをオプトインできるような仕組がある。ほぼ知られていないとおもうのだが、SalesforceSOAP API Endpointにはcrossdomain.xml が配置されている。場所はルートではなく https://xxx.salesforce.com/services/Soap/u/crossdomain.xml になるため、明示的にこのURLを指定してポリシーファイルをロードしなければいけない。

残念ながらまだXHR Level2には対応していないようなので、直接JavaScriptからXMLHttpRequestでリクエストを送るのは難しい。ということで、JavaScriptからはFlash経由でXHRをやるのがよいかもしれない。何らかのServer Proxyを用いてもいいが、サーバレスのポータビリティという利点は失われる。さらにAPIリクエストがクライアントIPから送られなくなるので、Salesforceの管理設定によって企業内ファイアウォールからのIP帯域にリクエストを制限をしている場合は使えない。後で示すサンプルコードはflXHRというライブラリを利用してFlash経由でクロスドメインリクエストを送信している。

Identity URL

ちなみに先のリダイレクトによるコールバックレスポンスの際に、idというパラメータにそのユーザのOpenIDのURLが渡されるようになっているのだが、そのURLはそのままREST形式のユーザ情報取得エンドポイントになっている。こちらはJSONPに対応しておりクロスドメインでリクエストができる。

Using Identity URLs

リクエスト方法としては、OpenIDのURLに対してOAuthのAccessTokenをパラメータとしてつけて以下のようにアクセスする。

https://login.salesforce.com/id/00Dx00000008mib/005x0000000I8It?oauth_token=00Dx0000000BV7z%21AR8AQBM8J_xr9kLqmZIRyQxZgLcM4HVi41aGtW0qW3JCzf5xdTGGGSoVim8FfJkZEqxbjaFbberKGk8v8AnYrvChG4qJbQo8&format=json&callback=callback


なお、もうしばらくすると現行のSOAP APIの他にRESTful APIが出てくるらしいく、このような形でおそらく何らかのクロスドメイン対応がされているのだろうと思われる。ということで今わざわざSOAP APIを使わなくてもいいわけだが、正直JavaScriptからSalesforce APIを利用するためにSalesforceが提供しているAJAX Toolkitが現段階でもなかなかよいWrapperになっているので、JavaScriptからアクセスする限りSOAPでもRESTでもそんなに変わらないだろう。

サンプルコード

最後に、せっかくなのだから、作ったコードは以下に公開しておく。HTMLページはSSLである必要があるのでS3に置いておいた。

https://stomita-lab.s3.amazonaws.com/sfdc-oauth2/hello.html


けれども、Salesforce OAuthのちょっとイケてないのは、誰かがこのコードを見てその場で実際に試そうとしても試すことができない、というところにある。

たとえば、上記のSalesforce OAuth2ログインのテストページは、もしあなたが何らかのSalesforceのアカウントを持っていたとしても、あなたの組織の管理者が事前に設定登録していない限り、OAuth認証フローが通らないようになっている。

SalesforceのOAuthの場合、どんなOAuthのコンシューマも事前にユーザ企業の管理者がそのコンシューマを登録設定しておかないと利用できない。これは一般的な開発者のコンシューマ登録とは別に行うことになる。開発者とユーザ企業がイコールの場合、つまり内製アプリケーションの場合はこれは問題ないが、外部サービスが複数のSalesforce導入企業にOAuth認証でサービスを行なおうとしたときには上記の設定をユーザ企業にお願いしなければならない。

設定登録といっても、具体的にはパッケージという設定の塊を組織内にコピーしてインストールするだけなので作業的には大した問題ではないのだけれど、管理者権限が必要というところで導入の敷居はちょっと高くなる。

このあたりはGoogle AppsのOAuthとかなり異なっている。Google Apps での 3-legged OAuthの場合、事前に管理者がそのコンシューマを受け入れていようがいまいが、ユーザが許可すればGDataでアクセスができる。まあEnterpriseなサービスとして見たとき、Appsの方がガバナンスを効かせられていない、という見方もできるので一概にSalesforceが劣っているというような批判をするつもりはない。また、Appsの方もいくつかのオプションがあるようなので、もしかしたらApps管理者は野良OAuthアプリのアクセスを許可しないようにできるのかもしれない。この点については判断を保留する。


とりあえず、上記のSalesforce OAuth2でログインしようと思った場合、こちらのパッケージを事前にSalesforce管理者にインストールしてもらわなければならない。

https://login.salesforce.com/?startURL=%2Fpackaging%2FinstallPackage.apexp%3Fp0%3D04tA0000000IMjA

ただ、このめんどくささによって、外部サイトにユーザパスワードを預ける悪習を取り払うことができずに、結局一部サービスはそのままに依ってしまうのではないかな、などと思う。

(追記:2011/03/04)
@metadaddy によると、Spring '11 によるアップデートで管理者パッケージインストールは要らなくなった模様。すばらしい。

3rd-party cookie について、Facebookの場合

昨日の Shibuya.js でmalaさんが話してたことの内に、3rd Party Cookie の是非があった。

http://www.ustream.tv/recorded/8605067

  • Shibuya.jsの第一部まとめ、みたいな感じのやつ

Shibuya.js beyond HTML5 に参加してきます - 北海道苫小牧市出身の初老PGが書くブログ

では3rd Party Cookieに対して、実際のサービスはどうなってるのか。はてなスターはてブくらいだったら、正直世界的には影響ないかもしれない。ブラウザの実装はこれらサービスのことなどたぶん何も考えずに進化していく可能性が高いんではないかな(すいません)。

でもFacebook(FB)は違う。ユーザ規模が大きすぎる。Facebookが使えないと困るので、ブラウザの実装がそっち側に揺れる可能性は十分ある。また、Facebookがやっているから、と、他のサービスが追従することもありえる。


最近でたFacebook Like(日本語だと「イイネ」)というのがある。

要は、これFacebookはてなスター、だと思っている。はてなスター同様JSを貼り付けるだけで導入できるので、かなりの数のWebサイトが導入してる。その点ではてなスターは先見の明があったのかもしれない。惜しむらくはソーシャルグラフが出来上がらないうちにサービスをやってしまったことか。まあ今回はそれについてはさておく。

Facebookは、Facebook Connect など、いろいろHackを多用してクロスドメインでのサービス提供に早くから取り組んでいたけれども、こちらはある意味あまり大したHackはない。ドメイン間のトークンのやりとりなどは含まれず、単に3rd Party Cookieによって認証された状態でiframeの中でPOSTしている。認証されていない場合はポップアップウィンドウが開く。

このパターンの良い点としては、トークンのやりとりを含まないので、OAuthなどにみられるリダイレクトや承認などめんどうさがない(ブログをふぁぼるのにいちいちいくつものサイトにアクセス許可与えたいか?)。悪い点としては、ユーザは常にトラックされているような感じになる(どのWebサイトに行っても自分のアイデンティティが表示されている)

はてスタのようにJSONPだと自動送信の3rd-party Cookieに依存するしかなくCSRFし放題になりがちだが、IFRAMEならもっとそのあたりうまくやれるかもしれない(Facebookが実際どうやっているかは詳しくは見ていない)。でも結局 3rd party cookie の送信はONでないと動かない。試しにOFFにしてやってみたらウィンドウオープンクローズが無限ループになったりする。


ちなみに、僕個人には、3rd-Party Cookieに対しての現在の状況について特に立場はなく、3rd party cookie OFFにしろ、とまではあまり思わないし、実際にそう設定はしていない。特に、以前に3rd-Party Cookieが問題になったのは、Ad Networkが無条件にトラッキングのためのCookieを食わせていたからと認識している。実際、今でも3rd-Party Cookieの受け入れはだいたいデフォルト拒否になっている。

ただ、今日のように普遍化してしまったFacebookにおいて、3rd-party cookie を受け入れるもなにもほとんどのユーザが既に受け入れている状態(日本人にはあまり実感わかないかもしれないけど)だから、前回のとはちょっと状況が違う気もする。いずれにせよFacebookは(Likeボタンとか特に関係なく)プライバシーという観点では結構叩かれているわけですね。

Twitter @Anywhere を斜め上に掘り下げる

Twitter @AnywhereというDeveloper向けの新サービスが出てた。このサービス、この自分的にはいろいろな理由によりちゃんとチェックしておく必要がある。ので久々にブログ書く。

Facebook Connect (JavaScript) を知ってる人は、それがTwitterでもできるようになった、と思ったらいい。つまりサーバレスでTwitterに接続してAPIJavaScriptから利用できるようになった。今でもJSONPである程度APIの利用はできたが、JSONPとは違い認証が必要な操作、例えば書き込み系の操作もOK(ただしversion 1のAPIでは許されている操作はそれほどない)。

詳しくはこちらの記事とかをどうぞ。

Twitter 新 API のドキュメント「Getting Started with @Anywhere」日本語訳 - WebOS Goodies

続きを読む

Google Friend Connect を使った OpenSocial Dashboard を作った

Social Web #4 でなかじまんさんに動画まで作ってもらってリークされてたりしましたが、当初考えてた最低限の機能はそろったので、ブログにあげます。

Google Code Archive - Long-term storage for Google Code Project Hosting.

ソースコードはこちら。

http://opensocial-dashboard.googlecode.com/svn/

デモンストレーションサイトもこちら。Google Code上で動いています。

http://opensocial-dashboard.googlecode.com/svn/trunk/index.html

で、昨日MA5の会場でプレゼンしてきましたので、その資料もついでに。

OpenSocial Dashboard


これを作った動機

見て分かるように、ガジェットコンテナの見栄えのいいかんじのものを作ったんですが、べつにMac OS Xダッシュボードみたいなアプリを作りたかったからという正統な動機によるものではなくって、どちらかというと僕がGoogle Friend Connect(GFC)とそのパラノイアっぷりを愛してたから、という若干ひねくれた理由によります。

あと、ブックマークレット呼び出しについては、linolino anywhereにちょっとだけインスパイアされてます。

中身

Google Friend Connect(GFC)の恩恵により、すべて HTML+JavaScript のみで動いています。レイアウトなどのデータの保存もOpenSocialのAppDataの中に格納しています(GFCにおける上限の10K以内にだいたい収まる)。ただし、ガジェットを追加する際に、定義ファイル(.xml)を取ってくるのにクロスドメインリクエストの送信が必要になるのですが、gadgets.io.makeRequestはGFC APIでは実装されていないので、以前作ったmakeRequestをガジェット経由でプロキシするやつをつかってます。で、そのへんの変更をサポートするためにOpenSocial jQueryもちょっといじってます。

重要だとおもってること

OpenSocial Dashboardは、ブックマークレットを利用して立ち上げることができます。その際、元ページに含まれている内容をコンテキスト情報として利用し、ガジェットに引き渡すことができるようになっています。

このコンテキスト情報からガジェットへ渡すパラメータへの変換はプラグインとなるJavaScriptファイルを書いてやれば任意に追加できます。(e.g. たとえば元ページのURLからASIN IDを抜き出すなど)。プラグインはコンテキスト情報からデータを抜き出し、その値はパラメータとしてガジェット描画時にview paramsとして渡されます。

現在はまだ実装していませんが、今後プラグインの中からはjQueryで元ページのDOMにアクセスしつつ、makeRequestを実装したOpenSocial jQuery の $.ajax メソッドによってクロスドメインリクエストが送信できるようになる予定です。つまりUbiquityあるいはGreasemonkeyに相当して使え、かつIEでも動きます。たぶん。さらに今後GFCでOAuth Proxy(3-legged OAuth)が利用できるようになったりしたらもっといいことあるんじゃないかな、などと思ってます。

今後たぶんやるだろうこと

  • UserPref項目をガジェット外部から設定できるようにする。すでにガジェット内部でセットされたPrefの永続化には対応してるので、純粋にUIの実装の問題。
  • PubSubの実装。昔 OpenSocial Hackathon でやったこととおなじで、ガジェット間で連携できるようになる。GFCはまだgadgets.rpcくらいしかつかえないので、自前で作る必要がある。
  • Profile以外の view への対応(canvas)。

MA5について

MA5への応募は、締め切り前日が休日だったのでやったようなもんですが、おそらく応募できるようになった時点での費やした時間は全部で24時間くらい(ほとんどがIllustratorでの画像リソース作り)です。応募締め切り後もちょっとずつ手を入れてるのでなんともいえないですが、しかしバックエンドを考えなくていいのは楽ですね。

このプレゼン資料も発表前日深夜に作ったKeynote資料です。みんなCMパロディのムービーとかMotionとか気合いいれてましたね。ひとりだけ勉強会ノリのプレゼンでしたので申し訳ない。

ちなみに初めて1ヶ月くらいの1人プロジェクトなのになぜかもう revision 1063 とかいってますが、これはGoogle Friend Connectが登録したサイト上でしかテストできないため、ファイルを保存するたびにレポジトリにコミットしてアップロードされたコンテンツにアクセスしてテスト、を繰り返してたからです。Googleには若干ながらご迷惑をおかけしていますことをここにお詫びいたします。

WEB+DB PRESS vol.53 - Google JavaScript API

今回は GoogleJavaScript API のことについて書いてます。よく使われる Maps API とかじゃなくって、GData JavaScriptとかVisualizationとか、あまり日の目を見てないところにスポット当てる感じです。

WEB+DB PRESS Vol.53

WEB+DB PRESS Vol.53

ちなみに連載途中(あと3回ある)ですが、もはやネタ的にも業務的にもきついので、つぎからエースに交代します。ほっ。

jQuery用 Live Clipboard プラグイン

その昔(3年以上前)MicrosoftLive Clipboardというのを発表していた。これに対応したサイトでは、Webアプリのデータを構造化した状態でコピー&ペーストしてアプリケーション間で持ち回ったり、クライアントソフトにコピーできたりする。なかなかおもしろかったが、その後どうなったのか知らない。なので思い出しついでにjQuery用のLive Clipboardもどきをつくった。

サンプル

http://liveclipboard-jquery.googlecode.com/svn/trunk/videosearch.html

Google動画検索結果をマウスで選択し、右クリックメニューから検索結果をクリップボードにコピーできる。
スプレッドシートに Ctrl(MacではCommand) + V でペーストすると、選択した動画の検索結果のデータがクリップボード内に保存されているのがわかる。

解説

アプリケーション間でコピーペーストを実現しようとすると、WebアプリからJavaScriptクリップボードにアクセスすることができない(IEではできるようだがデフォルトで警告が出る)ため、普通はコピーペーストが自由にできない。Flashを経由して使うという手もあるが、Flash 10 以降でセキュリティ制約に引っかかったり、回避しようとするとクリップボードアクセスする部品をFlashで作らなきゃいけなかったりしてちょっと使い勝手がよくない。

この Live Clipboard の種を明かすと、コピー/ペースト操作を仕込みたい要素に対して、textarea 要素を透明状態で上に重ね合わせて、右クリックやキーボードショートカットをフックしている。やり方はhack的で微妙だがクロスブラウザ環境での動作はそれなりに保証できる。

使い方

対象の要素に対して、クリップボードへのアクセスを処理する関数を登録する。

例:

$('.clippable').clipboard({

  /* コピーする値を文字列としてクリップボードへ返す */
  copy : function() { 
    // return $(this).text();
  },

  /* クリップボードから文字列を受けとって処理する */
  paste : function(data) { 
    // $(this).text(data);
  },

  /* 削除コマンドを受け取る(cut はcopy + del) */
  del : function() { 
    // $(this).remove();
  }

});

以降、要素を右クリックすると、ブラウザのコマンドメニューが現れて、コピー/カット/ペースト/削除などの操作ができる。paste および del を実装しない場合はコピーのみ可能になる。

対象要素をクリックした状態で、ショートカットキー(Ctrl + CXV, Delete)にも対応。

absolute 指定で重ねているため、要素の位置が変化したり消滅したりする場合は、適宜 $.trackClipboards() を呼び出して的確に重ね合わせてやる必要あり。

その他

参考までに、ドラッグドロップへの対応の話。Ext JSでやってる。イベントを透過させるテクニックはだいたい同じか。

http://www.vinylfox.com/forwarding-mouse-events-through-layers/

Salesforce が OAuth をサポート

情報キャッチ遅れた。今日やっと知った。正直彼らがWebサービス周りでアグレッシブなアーキテクチャ変更するとは思わなかったので、ちょっと意外だった。

Remote Access Applications with OAuth | Winter '10 | Releases

上記にはたいしたことは書いてないが、下記のリリースノートに若干記述がある。それ以外の(開発者にとって)有用な技術情報はまだ出てない(ような気がする)。

Salesforce.com Winter '10 Release Notes

ちなみにWinter'10とはSalesforceの最新バージョンで、既に有効になっている環境もある(Salesforceの場合サインアップしたときの条件によって別々のインスタンスがルールに従って割り与えられるため、アップグレードのタイミングもまちまち)が、この機能が使えるようになるのは若干ずれて 2009年10月12日以降らしい。なのでこの記事を書いている現時点ではもう少し待つ必要がある。

      • -

以下、想像に基づくため、実際の資料が出てきてから補足修正する予定で書く。

インパク

まず、Google Apps と異なり、もともとの出自が企業向けのサービスであった会社のサービスがOAuthに対応したこと。もちろんJIRAなどの例もあるが、知名度を考えると、これを皮切りに今後OAuthがエンタープライズ系プロダクトの世界にも広く採用される可能性は十分にある。

今までのWebサービスAPIはどうなるか?

SalesforceにはもともとSOAPベースのAPIがあるが、このAPIの認証はSOAPヘッダの中にセキュリティトークンとしてのSession IDを埋め込んでメッセージを送るという独自の仕様で実現されている。OAuthではHTTPボディとしてのSOAPエンベロープ内にAccess Tokenを設定することは考えられてないので、これはそのままではまったくOAuthと互換性がない。なのでSalesforce APIサービス側でこれに対処する必要がある。

やり方として、

  • 新たにOAuthを受け付けるRESTベースのAPIを導入する

がまず考えつくが、SalesforceWebサービスの稼働実績を考えると今からそちらに踏み切るのには開発者にもインフラにも双方にコストがかかりすぎる。なのでこれはあり得ないと思う。

おそらく

  • OAuthのAccess Tokenを従来のAPI認証に利用できるSession IDに変換する新たなAPIエンドポイントを設ける

のようなやり方になるのではないか。これであれば今までのAPIクライアントライブラリはほぼ使い回しができるし、インフラ側も特に負荷があがるわけではない。

Salesforceに対してOAuthコンシューマの登録はどのようになるのか

これは若干リリースノートに記載がある。ただ、Salesforceのアプリケーションパッケージングの仕組みを知っていないとちょっとわかりにくい。特に管理パッケージ(managed package)という記載が出てくるが、これはSalesforceインスタンス上で一意の名前空間をパッケージにつけるための仕組みになる。このパッケージにひもづけてOAuthコンシューマを登録することにより、Salesforce上で一意になるコンシューマを登録することができる。

ほかのOAuthサービスプロバイダと違う点は、Salesforceを契約した企業のシステム管理者が上記のパッケージをインストールしないと、その企業(組織)内のユーザはOAuth認証を利用できないという点。ちゃんと管理者が承認したものだけが利用できるのである意味ではセキュアだが、ある意味ではせっかくのOAuthなのにもかかわらずユーザセントリックではない。

OAuthコンシューマにはならないのか?

Salesforceを営業支援/CRMサービスとしてのみ認識していると気づきにくいが、SalesforceがOAuth対応、というときには考えられるパターンとして2種類あって、それはSalesforceがOAuthサービスプロバイダになるかあるいはコンシューマになるか、ということ。SalesforceにはApexという独自のプログラミング言語/実行環境があり、Salesforce上にホスティングしたプログラムから外部Webサービスにリクエストを投げられたりするので、Java/Perl/Ruby/Python/PHPなどと同じようにOAuthのコンシューマライブラリが提供される可能性はあり得る。僕自身、最初はサービスプロバイダではなくコンシューマでの対応の方だろうかと考えていた。
これについては、特に問題があるわけではないように思えるが、どうなのか。今回は同時ではないかもしれないが(Google Apps統合を中心にして)需要も多そうなのでいずれサポートされてもおかしくない。Salesforceの場合は複数の組織/アプリケーションが同一のURL上で共存できるマルチテナントであるためにちょっとめんどくさいことが多そうな気がするけれども。

OAuth対応はOpenSocial化への布石?

OpenSocial発足時にsalesforce.comも名を連ねていたことを覚えている人はそう思うかもしれない。もちろんそうであってくれるといいが、個人的には、何となくそれに関しては悲観的である。というのも、OpenSocialの想定しているSocial Graphと現在のSalesforceの想定する人間関係のモデルでは違いが大きすぎるし、何よりもまず、Social Graphとして開放することに対するビジネス要求がそれほどない。別の言い方をすると、データは既存のAPIで十分に開放されている。
OAuth対応についてのメインの動機は、リリースノートの例にもある通り iGoogle ガジェットからセキュアに(ユーザ/パスワードを保存させることなく)Salesforce内のデータにアクセスできるようにするためである気がしている。そしてこれはおそらくSalesforceGoogleへの(しばしば一方的な)愛による。