105

OAuth 対応アプリケーション、特に Mendeley ( http://dev .mendeley.com )、どうやら 3-legged OAuth を使用しています。

OAuth を使用するのはこれが初めてで、使い始めるのに非常に苦労しています。いくつかの .NET OAuth ライブラリまたはヘルパーを見つけましたが、必要以上に複雑に思えます。私がやりたいことは、Mendeley API に REST リクエストを発行し、応答を取得できるようにすることだけです!

これまでのところ、私は試しました:

最初の (DotNetOpenAuth) は、何時間も費やして方法を考えれば、必要なことを実行できるように思えます。2番目と3番目は、私が知る限り、Mendeleyが送り返している検証コードをサポートしていません.

Mendeley からコンシューマー キーとシークレットを取得しました。DotNetOpenAuth を使用して、ユーザーがアプリケーションに入力するための確認コードを提供する Mendeley ページでブラウザーを起動することができました。しかし、この時点で私は迷子になり、それをアプリケーションに適切に提供する方法を見つけることができませんでした。

どこから始めたらよいかわからないことを認めたいと思います (学習曲線はかなり急勾配のようですが) - 誰かが私を正しい方向に向けることができれば、感謝します!

4

1 に答える 1

185

仰るとおりです。.NETアプリで利用できるオープンソースのOAuthサポートクラスは、理解しにくく、複雑すぎ(DotNetOpenAuthによって公開されるメソッドの数は?)、設計が不十分です(そのGoogleのOAuthBase.csモジュールにある10個の文字列パラメーターを持つメソッドを見てください)。あなたが提供したリンク-状態管理はまったくありません)、またはそうでなければ不十分です。

これほど複雑である必要はありません。

私はOAuthの専門家ではありませんが、TwitterとTwitPicで正常に使用できるOAuthクライアント側マネージャークラスを作成しました。使い方は比較的簡単です。これはオープンソースであり、ここで入手できます:Oauth.cs

レビューのために、OAuth 1.0a ...ちょっと面白いことに、特別な名前があり、それは「標準」のように見えますが、私が知る限り、「OAuth1.0a」を実装する唯一のサービスはTwitterです。私はそれが十分に標準的だと思います。とにかく、OAuth 1.0aでは、デスクトップアプリで機能する方法は次のとおりです。

  1. アプリの開発者であるあなたは、アプリを登録して「消費者キー」と「消費者シークレット」を取得します。Arstechnicaには、このモデルが最適ではない理由についてのよく書かれた分析がありますが、彼らが言うように、それはそれが何であるかです

  2. アプリが実行されます。初めて実行するときは、Twitterとその姉妹サービス(TwitPicなど)に対してoauth認証されたRESTリクエストを行うために、ユーザーにアプリの承認を明示的に付与する必要があります。これを行うには、ユーザーによる明示的な承認を含む承認プロセスを実行する必要があります。これは、アプリを初めて実行したときにのみ発生します。このような:

    • 「リクエストトークン」をリクエストします。別名一時トークン。
    • Webページをポップし、そのリクエストトークンをクエリパラメータとして渡します。このWebページは、ユーザーにUIを表示し、「このアプリへのアクセスを許可しますか?」と尋ねます。
    • ユーザーはTwitterWebページにログインし、アクセスを許可または拒否します。
    • 応答のhtmlページが表示されます。ユーザーがアクセスを許可した場合、48ポイントのフォントで表示されたPINがあります
    • ユーザーは、そのピンをWindowsフォームボックスにカットアンドペーストして、[次へ]などをクリックする必要があります。
    • 次に、デスクトップアプリは「アクセストークン」に対してoauth認証されたリクエストを実行します。別のRESTリクエスト。
    • デスクトップアプリは「アクセストークン」と「アクセスシークレット」を受け取ります。

承認ダンスの後、デスクトップアプリは、ユーザー固有の「アクセストークン」と「アクセスシークレット」(およびアプリ固有の「コンシューマーキー」と「コンシューマーシークレット」)を使用して、ユーザーに代わって認証されたリクエストを実行できます。 Twitterに。ユーザーがアプリの承認を取り消す場合、Twitterが何らかの理由でアプリの承認を取り消す場合、またはアクセストークンやシークレットを紛失した場合は、承認ダンスを再度行う必要がありますが、これらは期限切れになりません。 。


賢くない場合は、UIフローはマルチステップのOAuthメッセージフローをミラーリングすることができます。より良い方法があります。

WebBrowserコントロールを使用して、デスクトップアプリ内で承認Webページを開きます。ユーザーが[許可]をクリックすると、そのWebBrowserコントロールから応答テキストを取得し、PINを自動的に抽出してから、アクセストークンを取得します。5つまたは6つのHTTPリクエストを送信しますが、ユーザーに表示する必要があるのは1つの[許可/拒否]ダイアログのみです。単純。

このような:
代替テキスト


UIを並べ替えた場合、残っている唯一の課題は、oauthで署名されたリクエストを生成することです。oauthの署名要件は特定のものであるため、これは多くの人をつまずかせます。これが、簡略化されたOAuthManagerクラスが行うことです。

トークンをリクエストするコード例:

var oauth = new OAuth.Manager();
// the URL to obtain a temporary "request token"
var rtUrl = "https://api.twitter.com/oauth/request_token";
oauth["consumer_key"] = MY_APP_SPECIFIC_KEY;
oauth["consumer_secret"] = MY_APP_SPECIFIC_SECRET;    
oauth.AcquireRequestToken(rtUrl, "POST");

それだけです。単純。コードからわかるように、oauthパラメーターを取得する方法は、辞書のような文字列ベースのインデクサーを使用することです。AcquireRequestTokenメソッドは、oauthで署名されたリクエストを、リクエストトークン(一時トークン)を付与するサービスのURLに送信します。Twitterの場合、このURLは「https://api.twitter.com/oauth/request_token」です。oauth仕様では、oauthパラメーターのセット(トークン、token_secret、nonce、timestamp、consumer_key、version、およびcallback)を、特定の方法(urlでエンコードされ、アンペアサンドで結合)、および字句的にパックする必要があるとされています-並べ替えられた順序で、その結果に署名を生成してから、同じパラメーターを署名と一緒にパックし、新しいoauth_signatureパラメーターに別の方法で(コンマで結合して)保存します。 OAuthマネージャークラスはこれを自動的に行います。 ナンスとタイムスタンプ、バージョンと署名が自動的に生成されます。アプリはそのようなことを気にしたり認識したりする必要はありません。oauthパラメータ値を設定し、簡単なメソッド呼び出しを行うだけです。マネージャークラスはリクエストを送信し、応答を解析します。

じゃあ、なに?リクエストトークンを取得したら、ユーザーが明示的に承認を与えるWebブラウザUIをポップします。あなたがそれを正しく行うならば、あなたはこれを埋め込みブラウザにポップするでしょう。Twitterの場合、このURLは「https://api.twitter.com/oauth/authorize?oauth_token=」にoauth_tokenが追加されています。次のようなコードでこれを行います。

var url = SERVICE_SPECIFIC_AUTHORIZE_URL_STUB + oauth["token"];
webBrowser1.Url = new Uri(url);

(これを外部ブラウザで実行している場合は、使用しますSystem.Diagnostics.Process.Start(url)。)

Urlプロパティを設定すると、WebBrowserコントロールはそのページに自動的に移動します。

ユーザーが[許可]ボタンをクリックすると、新しいページが読み込まれます。これはHTMLフォームであり、フルブラウザの場合と同じように機能します。コードで、WebBrowserコントロールのDocumentedCompletedイベントのハンドラーを登録し、そのハンドラーでピンを取得します。

var divMarker = "<div id=\"oauth_pin\">"; // the div for twitter's oauth pin
var index = webBrowser1.DocumentText.LastIndexOf(divMarker) + divMarker.Length;
var snip = web1.DocumentText.Substring(index);
var pin = RE.Regex.Replace(snip,"(?s)[^0-9]*([0-9]+).*", "$1").Trim();

これは、HTML画面のスクレイピングのビットです。

ピンをつかんだ後は、Webブラウザーはもう必要ないので、次のようにします。

webBrowser1.Visible = false; // all done with the web UI

...そして、Dispose()も呼び出したいと思うかもしれません。

次のステップは、そのピンと一緒に別のHTTPメッセージを送信することにより、アクセストークンを取得することです。これは別の署名されたoauth呼び出しであり、上記で説明したoauthの順序とフォーマットを使用して構築されています。しかし、繰り返しになりますが、これはOAuth.Managerクラスを使用すると非常に簡単です。

oauth.AcquireAccessToken(URL_ACCESS_TOKEN,
                         "POST",
                         pin);

Twitterの場合、そのURLは「https://api.twitter.com/oauth/access_token」です。

これでアクセストークンができ、署名されたHTTPリクエストで使用できます。このような:

var authzHeader = oauth.GenerateAuthzHeader(url, "POST");

...urlリソースエンドポイントはどこにありますか。ユーザーのステータスを更新するには、「http://api.twitter.com/1/statuses/update.xml?status=Hello」になります。

次に、その文字列をAuthorizationという名前のHTTPヘッダーに設定します。

TwitPicなどのサードパーティサービスとやり取りするには、次のようにわずかに異なるOAuthヘッダーを作成する必要があります。

var authzHeader = oauth.GenerateCredsHeader(URL_VERIFY_CREDS,
                                            "GET",
                                            AUTHENTICATION_REALM);

Twitterの場合、verifycredsurlとrealmの値はそれぞれ「https://api.twitter.com/1/account/verify_credentials.json」と「http://api.twitter.com/」です。

...そしてその認証文字列をX-Verify-Credentials-Authorizationと呼ばれるHTTPヘッダーに入れます。次に、送信するリクエストとともに、TwitPicなどのサービスに送信します。

それでおしまい。

まとめると、Twitterのステータスを更新するコードは次のようになります。

// the URL to obtain a temporary "request token"
var rtUrl = "https://api.twitter.com/oauth/request_token";
var oauth = new OAuth.Manager();
// The consumer_{key,secret} are obtained via registration
oauth["consumer_key"] = "~~~CONSUMER_KEY~~~~";
oauth["consumer_secret"] = "~~~CONSUMER_SECRET~~~";
oauth.AcquireRequestToken(rtUrl, "POST");
var authzUrl = "https://api.twitter.com/oauth/authorize?oauth_token=" + oauth["token"];
// here, should use a WebBrowser control. 
System.Diagnostics.Process.Start(authzUrl);  // example only!
// instruct the user to type in the PIN from that browser window
var pin = "...";
var atUrl = "https://api.twitter.com/oauth/access_token";
oauth.AcquireAccessToken(atUrl, "POST", pin);

// now, update twitter status using that access token
var appUrl = "http://api.twitter.com/1/statuses/update.xml?status=Hello";
var authzHeader = oauth.GenerateAuthzHeader(appUrl, "POST");
var request = (HttpWebRequest)WebRequest.Create(appUrl);
request.Method = "POST";
request.PreAuthenticate = true;
request.AllowWriteStreamBuffering = true;
request.Headers.Add("Authorization", authzHeader);

using (var response = (HttpWebResponse)request.GetResponse())
{
    if (response.StatusCode != HttpStatusCode.OK)
        MessageBox.Show("There's been a problem trying to tweet:" +
                        Environment.NewLine +
                        response.StatusDescription);
}

OAuth 1.0aは、内部的には複雑ですが、使用する必要はありません。OAuth.Managerは、発信oauthリクエストの生成、および応答でのoauthコンテンツの受信と処理を処理します。Request_tokenリクエストがoauth_tokenを提供する場合、アプリはそれを保存する必要はありません。Oauth.Managerは、それを自動的に実行するのに十分スマートです。同様に、access_tokenリクエストがアクセストークンとシークレットを返す場合、それらを明示的に保存する必要はありません。OAuth.Managerがその状態を処理します。

以降の実行では、アクセストークンとシークレットが既にある場合、次のようにOAuth.Managerをインスタンス化できます。

var oauth = new OAuth.Manager();
oauth["consumer_key"] = CONSUMER_KEY;
oauth["consumer_secret"] = CONSUMER_SECRET;
oauth["token"] = your_stored_access_token;
oauth["token_secret"] = your_stored_access_secret;

...次に、上記のように認証ヘッダーを生成します。

// now, update twitter status using that access token
var appUrl = "http://api.twitter.com/1/statuses/update.xml?status=Hello";
var authzHeader = oauth.GenerateAuthzHeader(appUrl, "POST");
var request = (HttpWebRequest)WebRequest.Create(appUrl);
request.Method = "POST";
request.PreAuthenticate = true;
request.AllowWriteStreamBuffering = true;
request.Headers.Add("Authorization", authzHeader);

using (var response = (HttpWebResponse)request.GetResponse())
{
    if (response.StatusCode != HttpStatusCode.OK)
        MessageBox.Show("There's been a problem trying to tweet:" +
                        Environment.NewLine +
                        response.StatusDescription);
}

OAuth.Managerクラスを含むDLLはここからダウンロードできます。そのダウンロードにはヘルプファイルもあります。または、ヘルプファイルをオンラインで表示できます。

このマネージャーを使用するWindowsフォームの例をここで参照してください。


実例

ここで説明するクラスと手法を使用するコマンドラインツールの実例をダウンロードします。

于 2010-12-16T17:03:12.310 に答える