Fork me on GitHub
QQ开放平台 OAUTH2.0 QqConnetSDK 登录,运行原理,附源码。

供大家研究使用,您可以对源代码进行修正编写。有很多不足,有很多缺点,在这里我只编写原理。

您需要开放式站点,做为了解它,您需要编写补充很多,或者您可以按照我的使用提供下载,进行编写其余内容补充及修正。谢谢大家,让大家的站点也融合这玩意。

开发环境:vs2005

QqConnetSDK

// 默认“Microsoft XML,v3.0”,其他版本也可以,只要能编译通过,步骤如下。
// 添加引用 -> “COM” 选项卡 -> 找到组件名称为“Microsoft XML,v3.0”

LoginToQQ.aspx     登录
QQCallback.aspx    回调访问页面
QqConnetSDK        项目sdk
      QqConnet  QqConnet基础类             ;您可以改进
      ConfigurationHandler 配置节点句柄类  ;用于扩展配置文件节点,您可以改进
      JSON      JSON分析类                 ;您可以改进
      UserInfo  用户实体类                 ;您可以改进,其他实体类不在一一列出,自行扩展。

web.config         站点配置文件
      <add key="OAUTH_CONSUMER_KEY" value="10000000" /> 您的 app id 
      <add key="OAUTH_CONSUMER_SECRET" value="AbcdAbcdAbcdAbcdAbcdAbcdAbcdAbcd" /> 您的 app key
      <add key="CALLBACK_URL" value="http://您的站点/QQCallback.aspx" /> 您的回调处理地址

QqConnetSDK    

View Code
using System;
using System.Data;
using System.Configuration;
using System.Text;
using System.Web;
using System.Web.UI.WebControls;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Reflection;
// 默认“Microsoft XML,v3.0”,其他版本也可以,只要能编译通过,步骤如下。
// 添加引用 -> “COM” 选项卡 -> 找到组件名称为“Microsoft XML,v3.0”
using MSXML2; 
using System.Net;
using System.Collections;
using System.Xml;
namespace QqConnetSDK
{
    /// <summary>
    /// QqConnet 基础类
    /// </summary>
    #region QqConnet
    public class QqConnet
    {
        private string QQ_OAUTH_CONSUMER_KEY;
        private string QQ_OAUTH_CONSUMER_SECRET;
        private string QQ_CALLBACK_URL;
        private string QQ_SCOPE;
        public string State = "";
        public QqConnet()
        {
            Hashtable table = ConfigurationManager.GetSection("QzoneGroups/QzoneSection") as Hashtable;
            this.VerifyQzoneSection(table);

            this.QQ_OAUTH_CONSUMER_KEY = table["OAUTH_CONSUMER_KEY"].ToString();//APP ID
            this.QQ_OAUTH_CONSUMER_SECRET = table["OAUTH_CONSUMER_SECRET"].ToString();//APP KEY
            this.QQ_CALLBACK_URL = table["CALLBACK_URL"].ToString();//回调地址。
            this.QQ_SCOPE = "get_user_info";//授权项

        }
        /// <summary>
        /// 检测QzoneSection节点
        /// </summary>
        /// <param name="table"></param>
        private void VerifyQzoneSection(Hashtable table)
        {
            if (table == null) this.ShowErrMsg("QzoneGroups/QzoneSection 不存在.", 0);
            if (table.Count <= 0) this.ShowErrMsg("QzoneGroups/QzoneSection 不存在.", 0);
            if (table["OAUTH_CONSUMER_KEY"] == null) this.ShowErrMsg("QzoneGroups/QzoneSection/OAUTH_CONSUMER_KEY 节点不存在.", 0);
            if (table["OAUTH_CONSUMER_SECRET"] == null) this.ShowErrMsg("QzoneGroups/QzoneSection/OAUTH_CONSUMER_SECRET 节点不存在.", 0);
            if (table["CALLBACK_URL"] == null) this.ShowErrMsg("QzoneGroups/QzoneSection/CALLBACK_URL 节点不存在.", 0);
        }
        public string APP_ID
        {
            get { return this.QQ_OAUTH_CONSUMER_KEY; }
        }
        /// <summary>
        /// State 数据.
        /// </summary>
        /// <returns></returns>
        private void GenerationState()
        {
            string value = Guid.NewGuid().ToString();
            this.State = value.Replace("-", "");
        }
        /// <summary>
        /// Get方法请求url,获取请求内容
        /// </summary>
        /// <param name="Url"></param>
        /// <returns></returns>
        public string RequestUrl(string Url)
        {
            ServerXMLHTTP xmlhttp = new ServerXMLHTTP();
            xmlhttp.setTimeouts(10000, 10000, 10000, 50000);
            xmlhttp.open("GET", Url, false, null, null);
            xmlhttp.send("");
            if (xmlhttp.readyState == 4)
            {
                return xmlhttp.responseText;
            }
            return "";
        }
        ///// <summary>
        ///// Post方法请求url,获取请求内容
        ///// </summary>
        ///// <param name="Url"></param>
        ///// <param name="data"></param>
        ///// <returns></returns>
        //public string RequestUrl_post(string Url, string data)
        //{
        //    ServerXMLHTTP xmlhttp = new ServerXMLHTTP();
        //    xmlhttp.setTimeouts(10000, 10000, 10000, 50000);
        //    xmlhttp.open("POST", Url, false, null, null);
        //    xmlhttp.setRequestHeader("Host", " graph.qq.com");
        //    xmlhttp.setRequestHeader("content-length ", data.Length.ToString());
        //    xmlhttp.setRequestHeader("content-type ", "application/x-www-form-urlencoded");
        //    xmlhttp.setRequestHeader("Connection", " Keep-Alive");
        //    xmlhttp.setRequestHeader("Cache-Control", " no-cache");
        //    xmlhttp.send(data);
        //    if (xmlhttp.readyState == 4)
        //    {
        //        return xmlhttp.responseText;
        //    }
        //    return "";
        //}
        /// <summary>
        /// 生成登录地址
        /// </summary>
        /// <returns></returns>
        public string GetAuthorization_Code()
        {
            this.GenerationState();

            string url, str;
            url = "https://graph.qq.com/oauth2.0/authorize";
            str = "client_id=" + this.QQ_OAUTH_CONSUMER_KEY;
            str += "&redirect_uri=" + this.QQ_CALLBACK_URL;
            str += "&response_type=code";
            str += "&scope=" + this.QQ_SCOPE;
            str += "&state=" + this.State;
            url = url + "?" + str;
            return url;
        }
        /// <summary>
        /// 检测是否合法
        /// </summary>
        /// <returns></returns>
        public bool VerifyCallback()
        {
            string Code = this.Request("code");
            string State = this.Request("state");
            if (Code != "")
            {
                return true;
            }
            return false;
        }
        /// <summary>
        /// 获取 access_token
        /// 示例.返回结果:正确 access_token=ABCDEFGABCDEFGABCDEFG&expires_in=7776000; 
        /// </summary>
        /// <returns></returns>
        public string GetAccess_Token()
        {
            string url, str, result;
            url = "https://graph.qq.com/oauth2.0/token";
            str = "client_id=" + this.QQ_OAUTH_CONSUMER_KEY;
            str += "&client_secret=" + this.QQ_OAUTH_CONSUMER_SECRET;
            str += "&redirect_uri=" + this.QQ_CALLBACK_URL;
            str += "&grant_type=authorization_code";
            str += "&code=" + this.Request("code");
            str += "&state=" + this.Request("state");
            url = url + "?" + str;
            result = RequestUrl(url);
            this.ShowErrMsg(result);

            result = result.Split('&')[0];
            result = result.Replace("access_token=", "");
            return result;
        }
        /// <summary>
        /// 获取Openid
        /// 示例.返回结果:正确 callback( {"client_id":"100000001","openid":"ABCDEFGABCDEFGABCDEFG"} ); 
        /// </summary>
        /// <returns></returns>
        public string GetOpenid(string Access_Token)
        {
            string url, str, result;
            url = "https://graph.qq.com/oauth2.0/me";
            str = "access_token=" + Access_Token;
            url = url + "?" + str;
            result = RequestUrl(url);
            this.ShowErrMsg(result);

            JSON j = new JSON(result);
            return j.GetValue("openid").ToString();
        }
        ///// <summary>
        ///// 发送记录到微博
        ///// </summary>
        ///// <param name="content">发送内容</param>
        ///// <returns></returns>
        //public string Post_Webo(string Access_Token, string Openid, string content)
        //{
        //    string url, str;
        //    url = "https://graph.qq.com/t/add_t";
        //    str = "oauth_consumer_key=" + this.QQ_OAUTH_CONSUMER_KEY;
        //    str += "&access_token=" + Access_Token;
        //    str += "&openid=" + Openid;
        //    str += "&content=" + content;
        //    return RequestUrl_post(url, str);
        //}
        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <returns></returns>
        public UserInfo GetUserInfo(string Access_Token, string Openid)
        {
            string url, str, result;
            url = "https://graph.qq.com/user/get_user_info";
            str = "oauth_consumer_key=" + this.QQ_OAUTH_CONSUMER_KEY;
            str += "&access_token=" + Access_Token;
            str += "&openid=" + Openid;
            url += "?" + str;
            result = RequestUrl(url);
            this.ShowErrMsg(result);

            JSON j = new JSON(result);
            UserInfo src = new UserInfo();
            src = j.Convert<UserInfo>(src);
            return src;
        }
        /// <summary>
        /// 显示错误提示信息
        /// </summary>
        /// <param name="error"></param>
        public void ShowErrMsg(string ErrMsg, params object[] ErrParams)
        {
            string error = "";
            if (ErrParams.Length > 0)
            {
                error = ErrMsg;
            }
            else
            {
                int num = ErrMsg.IndexOf("\"error\"");
                if (num != -1)
                {
                    JSON j = new JSON(ErrMsg);
                    string description = j.GetValue("error_description").ToString();
                    switch (description)
                    {
                        case "code is reused error": //错误提示:code代码已被使用,无法重复使用该代码。其他错误不在一一列出。
                            break;
                    }
                    error = ErrMsg;
                }
            }
            if (error != "")
            {
                HttpContext.Current.Response.Write(ErrMsg);
                HttpContext.Current.Response.End();
            }
        }
        /// <summary>
        /// 获取与设置服务端会话
        /// </summary>
        /// <returns></returns>
        public object Session(string name, params object[] value)
        {
            object result = "";
            if (value.Length > 0)
                HttpContext.Current.Session[name] = value[0];
            else
                result = HttpContext.Current.Session[name];
            return result == null ? "" : result;
        }
        /// <summary>
        /// 获取接收地址栏参数值
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public string Request(string name)
        {
            string value = HttpContext.Current.Request.QueryString[name];
            return value == null ? "" : value.Trim();
        }
    } 
    #endregion
    /// <summary>
    /// JSON 分析类
    /// </summary>
    #region JSON
    public class JSON
    {
        private string _json;
        /// <summary>
        /// 传入Json
        /// </summary>
        /// <param name="json"></param>
        public JSON(string json)
        {
            this._json = json;

        }
        /// <summary>
        /// 获取指定名称的值
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public object GetValue(string name)
        {
            try
            {
                string value = this._json.Split(new string[] { "" + name + "\":\"" }, StringSplitOptions.RemoveEmptyEntries)[1];
                value = value.Split(new string[] { "\"" }, StringSplitOptions.RemoveEmptyEntries)[0];
                return value;
            }
            catch (Exception)
            {
                return null;
            }
        }
        /// <summary>
        /// 转化为提供的实体类
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="NewT"></param>
        /// <returns></returns>
        public T Convert<T>(T NewT)
        {
            PropertyInfo[] properties = typeof(T).GetProperties();
            foreach (PropertyInfo propertyInfo in properties)
            {
                string Name = propertyInfo.Name;
                object value = this.GetValue(Name);
                if (value == null) { NewT = default(T); break; }
                propertyInfo.SetValue(NewT, value, null); //默认字符型处理.
            }
            return NewT;
        }
    } 
    #endregion
    /// <summary>
    /// ConfigurationHandler 配置节点句柄类
    /// </summary>
    #region ConfigurationHandler
    public class ConfigurationHandler : IConfigurationSectionHandler
    {
        public virtual object Create(Object parent, Object context, XmlNode node)
        {
            Hashtable m_Config = new Hashtable();
            foreach (XmlNode child in node.ChildNodes)
            {
                m_Config.Add(child.Attributes["key"].Value, child.Attributes["value"].Value);
            }
            return m_Config;
        }
    } 
    #endregion
    /// <summary>
    /// UserInfo  用户实体类
    /// </summary>
    #region UserInfo
    public class UserInfo
    {
        private string _nickname;
        public string nickname
        {
            set { this._nickname = value; }
            get { return this._nickname; }
        }
        private string _figureurl;
        public string figureurl
        {
            set { this._figureurl = value; }
            get { return this._figureurl; }
        }
        private string _figureurl_1;
        public string figureurl_1
        {
            set { this._figureurl_1 = value; }
            get { return this._figureurl_1; }
        }
        private string _figureurl_2;
        public string figureurl_2
        {
            set { this._figureurl_2 = value; }
            get { return this._figureurl_2; }
        }
        private string _gender;
        public string gender
        {
            set { this._gender = value; }
            get { return this._gender; }
        }
        private string _vip;
        public string vip
        {
            set { this._vip = value; }
            get { return this._vip; }
        }
        private string _level;
        public string level
        {
            set { this._level = value; }
            get { return this._level; }
        }
        private string _is_yellow_year_vip;
        public string is_yellow_year_vip
        {
            set { this._is_yellow_year_vip = value; }
            get { return this._is_yellow_year_vip; }
        }
    } 
    #endregion
}

登录

View Code
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using QqConnetSDK;
public partial class LoginToQQ : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        GetRequestToken();
    }
    private void GetRequestToken()
    {
        QqConnet qc = new QqConnet();
        string url = qc.GetAuthorization_Code();
        string state = qc.State;

        Response.Redirect(url);
    }
}

 回调访问页面

View Code
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using QqConnetSDK;

public partial class QQCallback : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        req();
    }
    private void req()
    {
        QqConnet qc = new QqConnet();
        if (!qc.VerifyCallback())
        {
            qc.ShowErrMsg("参数缺少.");
        }

        //数据令牌
        string Access_Token = qc.GetAccess_Token();

        //唯一标识 Openid与QQ号一对一对应
        string Openid = qc.GetOpenid(Access_Token);

        //获取当前登录用户
        UserInfo User = qc.GetUserInfo(Access_Token, Openid);
        if (User != null)
        {
            this.result.Text = "成功登录.";
            this.Nickname.Text = User.nickname;
            this.Figureurl.ImageUrl = User.figureurl;

            qc.Session("QzoneOauth", User);
        }
    }
}


提供下载:https://files.cnblogs.com/DreamWu/QqConnet.zip

****************************************************
本文所有代码都来自 dream wu 编写。
****************************************************
 
 
posted on 2013-01-20 22:11  HackerVirus  阅读(1171)  评论(1编辑  收藏  举报