[C#]QQ开放平台(QQ站外登录)_流程和源码示例[原创]
本人阿旭,近期研究QQ开放平台的程序开发。因为使用.NET语言,到官方SDK下载竟然是一个DLL,下来经过反编译也没搞清楚怎么弄,晕菜。后来网上见一PHP源码,写的不错,按其原理,开发成了C#语言,本示例程序使用的OAuth2.0,是目前最新执口版本,写下来希望对大家有所帮忙。
本文内容
QQ开放平台(QQ登录)开发介绍
QQ开放平台是针对QQ网站以外的网站开发的信息共享接口,各网站通过实现QQ代码实现,可以与QQ网站的交换数据。本文说的是腾讯的OpenID开发,相关OpenID的相关文章,是有相关技术标准的,大家可以看百科会更详细。简单来说,就是说,在用户登录网站时,只使用绑定QQ的QQ帐号进行登录即可,无需每次去输入各网站的密码...
准备工作
访问:http://opensns.qq.com/,点击(图1)上的QQ登录链接,然后点击(图2)中“申请加入”链接,输入你的QQ帐号进行QQ登录验证,点击(图3)中的“添加网站/应用”链接。输入网站相关信息和网站验证后,会显示(图4)显示的管理中心界面。上面显示着AppID和AppKey,下面的程序中将会用到,保密数据,请误泄露哈!
图1
图2
图3
图4
QQ开放平台中QQ登录程序运行流程
1、客户端浏览器转向QQ验证页面,用户输入用户名密码后,QQ网站回调回开发者网站,并传回Authorization Code。
2、开发者网站发送获取到的Authorization Code后,将Authorization Code和AppID、AppKey使用Http协议发送给腾讯,腾讯验证后返回登录结果。
3、如果验证成功,返回用户的OpenID,OpenID是登录用户登录后的在开发者网站中唯一标识,升度为32位,字符范围为0-9A-F。
示例程序源码
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Net; using System.IO; using System.Text; using System.Web.Script.Serialization; using System.Collections.Specialized; using System.Text.RegularExpressions; public partial class _Default : System.Web.UI.Page { private static Random RndSeed = new Random(); public string GenerateRndNonce() { return (RndSeed.Next(1, 0x5f5e0ff).ToString("00000000") + RndSeed.Next(1, 0x5f5e0ff).ToString("00000000") +
RndSeed.Next(1, 0x5f5e0ff).ToString("00000000") + RndSeed.Next(1, 0x5f5e0ff).ToString("00000000")); } public string file_get_contents(string url,Encoding encode) { HttpWebRequest request=(HttpWebRequest)HttpWebRequest.Create(url); WebResponse response= request.GetResponse(); using(MemoryStream ms=new MemoryStream()) { using(Stream stream =response.GetResponseStream()) { int readc; byte[] buffer=new byte[1024]; while((readc=stream.Read(buffer,0,buffer.Length))>0) { ms.Write(buffer,0,readc); } } return encode.GetString(ms.ToArray()); } } NameValueCollection ParseJson(string json_code) { NameValueCollection mc= new NameValueCollection(); Regex regex = new Regex(@"(\s*\""?([^""]*)\""?\s*\:\s*\""?([^""]*)\""?\,?)"); json_code=json_code.Trim(); if(json_code.StartsWith("{")) { json_code=json_code.Substring(1,json_code.Length-2); } foreach (Match m in regex.Matches(json_code)) { mc.Add(m.Groups[2].Value, m.Groups[3].Value); //Response.Write(m.Groups[2].Value + "=" + m.Groups[3].Value + "<br/>"); } return mc; } NameValueCollection ParseUrlParameters(string str_params) { NameValueCollection nc = new NameValueCollection(); foreach (string p in str_params.Split('&')) { string[] p_s = p.Split('='); nc.Add(p_s[0], p_s[1]); } return nc; } protected void Page_Load(object sender, EventArgs e) { //应用的APPID string app_id = "粘贴你的APPID"; //应用的APPKEY string app_secret = "粘贴你的APPKey"; //成功授权后的回调地址 string my_url = "http://www.yourSite.cn/Default.aspx"; //Step1:获取Authorization Code //session_start(); string code = Request.QueryString["code"]; if (string.IsNullOrEmpty(code)) { //state参数用于防止CSRF攻击,成功授权后回调时会原样带回 Session["state"] = GenerateRndNonce();//md5(uniqid(rand(), TRUE)); //拼接URL string dialog_url = "https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=" + app_id + "&redirect_uri=" + Server.UrlEncode(my_url) + "&state=" + Session["state"]; Response.Write("<script> location.href='" + dialog_url + "'</script>"); Response.End(); } //Step2:通过Authorization Code获取Access Token if (Request["state"].ToString().Equals(Session["state"].ToString())) { //拼接URL string token_url = "https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&" + "client_id=" + app_id + "&redirect_uri=" + Server.UrlEncode(my_url) + "&client_secret=" + app_secret + "&code=" + code; string response = file_get_contents(token_url, Encoding.UTF8); NameValueCollection msg; if (response.IndexOf("callback") != -1) { int lpos = response.IndexOf("("); int rpos = response.IndexOf(")"); response = response.Substring(lpos + 1, rpos - lpos - 1); msg = ParseJson(response); if (!string.IsNullOrEmpty(msg["error"])) { Response.Write("<h3>error:</h3>" + msg["error"].ToString()); Response.Write("<h3>msg :</h3>" + msg["error_description"]); Response.End(); return; } } //Response.Write(response); //Step3:使用Access Token来获取用户的OpenID NameValueCollection ps = ParseUrlParameters(response); //*parse_str($response, $params); string graph_url = "https://graph.qq.com/oauth2.0/me?access_token=" + ps["access_token"]; string str = file_get_contents(graph_url, Encoding.Default); if (str.IndexOf("callback") != -1) { int lpos = str.IndexOf("("); int rpos = str.IndexOf(")"); str = str.Substring(lpos + 1, rpos - lpos - 1); } NameValueCollection user = ParseJson(str); if (!string.IsNullOrEmpty(user["error"])) { Response.Write("<h3>error:</h3>" + user["error"]); Response.Write("<h3>msg :</h3>" + user["error_description"]); Response.End(); } Response.Write("Hello " + user["openid"]); } else { Response.Write("The state does not match. You may be a victim of CSRF.request=" + Request["state"] + ",session=" + Session["state"]); } Response.End(); } }
本地测试方法
1、用记事本打开:C:\Windows\System32\drivers\etc\hosts文件
2、新增行“127.0.0.1 域 名”,比如:127.0.0.1 www.jishu.me即可(当前这个域名必须是QQ开放平台“添加网站/应用”时输入的域名,否则会报错)。
3、重新启动IE浏览器后,输入域名即可访问本地站点,注意IIS中绑定的IP要与Host文件中指定的IP一致。
版所所有阿旭博客,如要转载,请注明来源:http://www.cnblogs.com/a-xu/archive/2012/04/07/qq_login.html