我同意你的看法。可用于.NET应用程序的开源OAuth支持类很难理解,过于复杂(DotNetOpenAuth公开了多少种方法?),设计欠佳(请查看该Google的OAuthBase.cs模块中具有10个字符串参数的方法)您提供的链接-根本没有状态管理),否则就不能令人满意。
不需要这么复杂。
我不是OAuth专家,但是我制作了一个OAuth客户端管理器类,该类已成功用于Twitter和TwitPic。使用起来比较简单。它是开源的,可以在这里找到:Oauth.cs
为了进行审查,在OAuth 1.0a ...有点有趣的情况下,有一个特殊的名称,它看起来像是“标准”,但据我所知,唯一实现“ OAuth 1.0a”的服务是Twitter。我想这已经足够标准了。好的,无论如何,在OAuth 1.0a中,它对桌面应用的工作方式是这样的:
您,该应用程序的开发者,注册该应用程序并获得“消费者密钥”和“消费者秘密”。在Arstechnica,还有为什么这种模式是不是最好的一个写得很好的分析,但他们说,这是它是什么。
您的应用运行。首次运行时,它需要使用户明确批准该应用程序的批准,以便向Twitter及其姊妹服务(例如TwitPic)发出经oauth认证的REST请求。为此,您必须经过批准过程,涉及用户的明确批准。这仅在应用程序首次运行时发生。像这样:
- 请求一个“请求令牌”。又名临时令牌。
- 弹出网页,将该请求令牌作为查询参数传递。该网页向用户显示UI,询问“您是否要授予对此应用程序的访问权限?”
- 用户登录到Twitter网页,并授予或拒绝访问。
- 出现响应html页面。如果用户已授予访问权限,则会以48点字体显示PIN
- 用户现在需要将图钉剪切/粘贴到Windows窗体框中,然后单击“下一步”或类似内容。
- 然后,桌面应用程序会对“访问令牌”进行经过oauth身份验证的请求。另一个REST请求。
- 桌面应用会收到“访问令牌”和“访问密码”。
在批准舞蹈之后,桌面应用程序可以仅使用用户特定的“访问令牌”和“访问秘密”(以及应用程序特定的“消费者密钥”和“消费者秘密”)来代表用户执行经过身份验证的请求到Twitter。这些不会过期,尽管如果用户取消了对应用程序的授权,或者如果Twitter由于某种原因取消了对应用程序的授权,或者如果您丢失了访问令牌和/或机密,则需要再次进行批准操作。
如果您不聪明,则UI流程可以类似于多步OAuth消息流程的镜像。有个更好的方法。
使用WebBrowser控件,然后在桌面应用程序中打开授权网页。当用户单击“允许”时,从该WebBrowser控件中获取响应文本,自动提取PIN,然后获取访问令牌。您发送5或6个HTTP请求,但用户只需要看到一个“允许/拒绝”对话框。简单。
像这样:
如果您已经对UI进行了排序,那么剩下的唯一挑战就是生成oauth签名的请求。因为oauth签名要求有些特殊,所以这使很多人绊倒了。这就是简化的OAuth Manager类的作用。
请求令牌的示例代码:
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,该URL授予请求令牌(也称为临时令牌)。对于Twitter,此URL为“ https://api.twitter.com/oauth/request_token ”。oauth规范表示,您需要以某种方式(URL编码并由&符组合)并以字典上的方式打包oauth参数集(令牌,token_secret,随机数,时间戳,consumer_key,版本和回调)。排序后,在结果上生成签名,然后将这些相同的参数与签名一起打包,并以不同的方式(存储在新的oauth_signature参数中)(以逗号分隔)。 OAuth管理器类会自动为您执行此操作。 它会自动生成随机数,时间戳,版本和签名 -您的应用无需关心或注意这些内容。只需设置oauth参数值并进行简单的方法调用即可。manager类发出请求并为您解析响应。
好那怎么了 获得请求令牌后,将弹出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屏幕抓取。
抓住图钉之后,您就不再需要网络浏览器,因此:
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,验证凭据url和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窗体示例。
工作实例
下载使用此处描述的类和技术的命令行工具的工作示例: