参考阿旭的代码 本人整理并添加注释 和获取用户信息
View Code
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; namespace QQLogin { public partial class Default : System.Web.UI.Page { 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/index.aspx"; //Step1:获取Authorization Code 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(); //返回 my_url?code=... } //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; } } //Step3:使用Access Token来获取用户的OpenID NameValueCollection ps = ParseUrlParameters(response);//格式 access_token=..&expires_in=3600 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);//格式 callback( {"client_id":"YOUR_APPID","openid":"YOUR_OPENID"} ); if (!string.IsNullOrEmpty(user["error"])) { Response.Write("<h3>error:</h3>" + user["error"]); Response.Write("<h3>msg :</h3>" + user["error_description"]); Response.End(); } Session["openid"] = user["openid"]; Response.Redirect("Login.aspx"); } else { Response.Write("The state does not match. You may be a victim of CSRF.request=" + Request["state"] + ",session=" + Session["state"]); } Response.End(); } #region 获取随机数 private static Random RndSeed = new Random(); /// <summary> /// 获取随机数 /// </summary> /// <returns></returns> public string GenerateRndNonce() { return RndSeed.Next(100000, 999999).ToString("000000"); } #endregion #region 请求URL 返回数据 /// <summary> /// 请求url返回数据,默认get /// </summary> /// <param name="url">请求地址</param> /// <param name="encode">编码格式</param> /// <returns></returns> 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()); } } #endregion #region 处理请求返回数据转换成 K/V 格式供使用 /// <summary> /// 把json 数据转换成 key value格式 /// </summary> /// <param name="json_code">格式如callback( {"client_id":"YOUR_APPID","openid":"YOUR_OPENID"} ); </param> /// <returns></returns> 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); } return mc; } /// <summary> /// 把返回的参数以keyvalue存起来 /// </summary> /// <param name="str_params">格式如access_token=..&expires_in=3600</param> /// <returns></returns> 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; } #endregion #region 成功授权后 获取用户信息及返回用户信息参考表 /// <summary> /// 通过条件获取用户信息 如 用户昵称、头像URL、性别、 /// </summary> /// <param name="access_token"></param> /// <param name="appid"></param> /// <param name="openid"></param> /// <returns></returns> public NameValueCollection GetUserInfo(string access_token, string appid, string openid) { NameValueCollection user = new NameValueCollection(); string url = string.Format("https://graph.qq.com/user/get_info?access_token={0}&oauth_consumer_key={1}&openid={3}&format=json", access_token, appid, openid);//user_ string str = file_get_contents(url, Encoding.UTF8); if (!string.IsNullOrEmpty(str)) { int lpos = str.IndexOf("("); int rpos = str.IndexOf(")"); str = str.Substring(lpos + 1, rpos - lpos - 1); } user = ParseJson(str); return user; } /* ret 返回码。0 表示正确 errcode 二级错误码,详见:【QQ登录】微博私有返回码说明。 msg 如果ret不为0,会有相应的错误信息提示,返回数据全部用UTF-8编码。 data 登录用户的详细信息列表。 name 登录用户的帐号名。 openid 登录用户的唯一ID,与name一一对应。 nick 登录用户昵称。 head 登录用户头像url。 location 登录用户所在地。 isvip 登录用户是否为微博认证用户(0:不是; 1:是)。 isent 登录用户是否为企业机构(0:不是; 1:是)。 introduction 登录用户的个人介绍。 verifyinfo 认证信息。 birth_year 登录用户出生年。 birth_month 登录用户出生月份。 birth_day 登录用户出生日。 country_code 登录用户所在的国家代码。国家名称与代码的对应关系请参见国家城市名称对应代码列表。 province_code 登录用户所在的省代码。省份名称与代码的对应关系请参见国家城市名称对应代码列表。 city_code 登录用户所在的城市代码。城市名称与代码的对应关系请参见国家城市名称对应代码列表。 sex 登录用户性别(1:男; 2:女; 0:未填写)。 fansnum 登录用户听众数。 idolnum 登录用户收听的人数。 tweetnum 登录用户发表的微博数。 tag 标签信息列表。 id 个人标签id。 name 标签名。 edu 登录用户教育信息列表。 id 教育信息记录ID。 year 入学年。 schoolid 学校ID。 学校ID与学校具体信息的对应关系请参见教育信息数据库。 departmentid 院系ID。 院系ID与院系具体信息的对应关系请参见教育信息数据库。 level 学历级别。 email 用户注册的邮箱。*/ #endregion } }