最近想搞写一个基于QQ微博的桌面应用,按照官方的介绍,我使用C#的SDK进行开发,但是发现这个SDK关于登陆的地方很粗糙,另外发现通过OAuth的方式登陆的话,需要用户去填写获取到的verifer字符串。 研究了一下,发现C#里面可以通过一个Webbrowser来解决这个问题。基于这个机制,我写了一个登陆的辅助类。
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.Threading;namespace QQWeiboApi{ public partial class FrmTencentAuth : Form { private volatile bool is_run; public FrmTencentAuth() { InitializeComponent(); } public string GetOauthVerifier(IWin32Window win, string tokenKey, string callbackurl) { string url = "http://open.t.qq.com/cgi-bin/authorize?oauth_token=" + tokenKey; is_run = true; webBrowser1.Navigate(url); this.Show(win); while (is_run == true && (webBrowser1.Url == null || ! webBrowser1.Url.ToString().StartsWith(callbackurl))) { Application.DoEvents(); } if (is_run == false) { return null; } url = webBrowser1.Url.ToString(); this.Close(); string sl = "oauth_verifier="; return url.Substring(url.IndexOf(sl) + sl.Length); } private void FrmTencentAuth_FormClosing(object sender, FormClosingEventArgs e) { is_run = false; } }}
上面是验证form的一部分,下面的是处理登陆的代码:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using QWeiboSDK;using System.Collections.Specialized;using System.Reflection;namespace QQWeiboApi{ public class QWeiboLoginHelper { private string appKey = null; private string appSecret = null; private string accessKey = null; private string accessSecret = null; private string requestKey = null; private string requestSecret = null; private string verifier = null; private string callbackurl = "http://www.smallbridge.co.cc"; public QWeiboLoginHelper(string appKey, string appSecret) { this.appKey = appKey; this.appSecret = appSecret; } /// /// 登陆 /// /// 应用的key /// 应用secret public void Login() { GetRequestToken(appKey, appSecret); GetUserAuth(); GetAccessToken(); } public OauthKey AuthKey { get { if (appKey == null || appSecret == null || accessKey == null || accessSecret == null) { return null; } return new OauthKey() { customKey = appKey, customSecret = appSecret, tokenKey = accessKey, tokenSecret = accessKey }; } } private void GetAccessToken() { string url = "https://open.t.qq.com/cgi-bin/access_token"; List parameters = new List (); OauthKey oauthKey = new OauthKey(); oauthKey.customKey = appKey; oauthKey.customSecret = appSecret; oauthKey.tokenKey = requestKey; oauthKey.tokenSecret = requestSecret; oauthKey.verify = verifier; try { QWeiboRequest request = new QWeiboRequest(); string result = request.SyncRequest(url, "GET", oauthKey, parameters, null); NameValueCollection nvs = ParseKVPairs(result); accessKey = nvs["oauth_token"]; accessSecret = nvs["oauth_token_secret"]; if (accessKey == null || accessSecret == null) { throw new Exception("get null accessKey or accessSecret"); } } catch (Exception ex) { throw new Exception("get accessKey and accessSecret error", ex); } } private void GetUserAuth() { FrmTencentAuth frmau = new FrmTencentAuth(); try { verifier = frmau.GetOauthVerifier(null, requestKey, callbackurl); if (verifier == null) { throw new Exception("get null user oauth verifier"); } } catch (Exception ex) { throw new Exception("get user oauth verifier error", ex); } } private void GetRequestToken(string appKey, string appSecret) { string url = "https://open.t.qq.com/cgi-bin/request_token"; List parameters = new List (); OauthKey oauthKey = new OauthKey(); oauthKey.customKey = appKey; oauthKey.customSecret = appSecret; oauthKey.callbackUrl = callbackurl; try { QWeiboRequest request = new QWeiboRequest(); string result = request.SyncRequest(url, "GET", oauthKey, parameters, null); NameValueCollection nvs = ParseKVPairs(result); requestKey = nvs["oauth_token"]; requestSecret = nvs["oauth_token_secret"]; if (requestKey == null || requestSecret == null) { throw new Exception("get null request key or secret"); } } catch (Exception ex) { throw new Exception("get request key and secret error", ex); } } private NameValueCollection ParseKVPairs(string str) { NameValueCollection nvs = new NameValueCollection(); foreach (string kv in str.Split('&')) { string[] kvs = kv.Split('='); if (kvs.Length == 2) { nvs.Add(kvs[0], kvs[1]); } } return nvs; } }}
代码下载,请点 。