最近在作一个项目时,客户要求网站可以集成QQ登陆的功能,之前没作过这方面的开发,因而去QQ的开放平台官网研究了一下相关资料,通过本身的艰苦探索,终于实现了集成QQ登陆的功能,如今把相关的开发经验总结一下,但愿对有这方面需求的朋友有所帮助。html
一.前期准备服务器
首先你须要登陆QQ的开发平台注册一个帐号,QQ互联平台官方地址:http://connect.qq.com/ 进去后注册一个开发帐号,完了登陆后台会有相似以下的一个后台,填好相关信息,具体能够参考下图。最后咱们会有一个APP ID和APP KEY ,有了这两个东西才能实现后面的集成QQ登陆功能。app
二.开发工做dom
当咱们的帐号审核后,QQ开发平台会给咱们一个APP ID和APP KEY,有了这两个,咱们就能够进行开发的工做了。
QQ的登陆采用的是OAuth2.0协议,OAuth(开放受权)是一个开放标准,容许用户受权第三方网站访问他们存储在另外的服务提供者上的信息,而不须要将用户名和密码提供给第三方网站或分享他们数据的全部内容。具体的内容能够参考QQ的API文档http://wiki.connect.qq.com/oauth2-0%e7%ae%80%e4%bb%8b
QQ的开发平台已经有PHP,JAVA,JS等版本的SDK了,若是是要用到这些语言进行开发的能够直接参考这些SDK,我这边直接讲一下ASP.NET版本(MVC)的开发。网站
第一步.先在WebConfig中的 <appSettings>节点下加入以下配置编码
<add key="QQAppID" value="QQ平台给的APP ID" /> <add key="QQAppKey" value="QQ开发平台给的APP KEY"/> <add key="QQCallBack" value="http://www.mylanqiu.com/Account/QQConnect/"/> <add key="QQAuthorizeURL" value="https://graph.qq.com/oauth2.0/authorize" />
第二步.在Controllers中加一个登录的Action(我这边用的是MVC的开发方式,若是是传统.NET的能够直接在.aspx的Page_Load事件里加以下方法)url
public ActionResult LoginQQ() { string state = new Random(100000).Next(99, 99999).ToString();//随机数 Session["QQState"] = state; string appID = ConfigurationManager.AppSettings["QQAppID"]; string qqAuthorizeURL = ConfigurationManager.AppSettings["QQAuthorizeURL"]; string callback = ConfigurationManager.AppSettings["QQCallBack"]; string authenticationUrl = string.Format("{0}?client_id={1}&response_type=code&redirect_uri={2}&state={3}", qqAuthorizeURL, appID, callback, state);//互联地址 return new RedirectResult(authenticationUrl); }
这一步主要是实现去QQ平台进行身份验证,直观点也就是点击后会去出现以下截图的画面spa
第三步.在点击了上图的赞成登陆后(也就是已经使用QQ号在QQ平台登陆),QQ平台会经过咱们上面配置的回调地址也就是我这边填的http://www.mylanqiu.com/Account/WeiboConnect/返回到这个页面,并会返回一个code给咱们,咱们到时会使用这个code再去QQ开发平台获取access_token,并经过这个access_token获取登陆的相关用户信息。具体代码以下:code
/// <summary> /// QQ回调页面 /// </summary> public ActionResult QQConnect() { if (!string.IsNullOrEmpty(Request.Params["code"]) && !string.IsNullOrEmpty(Request.Params["state"])) { var code = Request.Params["code"]; var state = Request.Params["state"]; string requestState = Session["QQState"] == null ? "" : Session["QQState"].ToString(); if (state == requestState) { try { QQOAuthHelper QAuthHelper = new QQOAuthHelper();//这是一个辅助类,代码会在下面给出 QQOauthInfo qqOauthInfo = QAuthHelper.GetOauthInfo(code); string openID = QAuthHelper.GetOpenID(qqOauthInfo);//获取用的OpenID,这个ID是QQ给咱们的用户的惟一ID,能够做为咱们系统用户惟一性的判断存在咱们本身的库中 Session["QQOpenID"] = openID; string nickName = QAuthHelper.GetUserInfo(qqOauthInfo, openID);//获取用户的昵称 UserAccount userAccount = AccountBLL.GetUserAccountByOpenID(OAuthPlatform.QQ.ToString(), openID); if (userAccount != null)//判断是不是已用该OpenID是否已在咱们的库中,若已存在则容许登陆 { SetAuthCookie(userAccount); Response.Write("<script> window.opener.location.reload();window.close();</script>"); } ViewData["NickName"] = nickName; } catch (Exception ex) { return new RedirectResult("~/Error/Error.htm"); } } else { return new RedirectResult("~/Error/Error.htm"); } } else { return new RedirectResult("~/Error/Error.htm"); } return View(); }
经过上面的步骤就能够实现网站集成QQ登陆了。下面给出辅助类的源代码:orm
using System; using System.Text; using System.Configuration; using System.Collections.Generic; using System.Linq; using System.Net; using System.Web; using System.IO; namespace Com.ABC.Mylanqiu.BLL { public class QQOAuthHelper { string appID = ConfigurationManager.AppSettings["QQAppID"]; string appKey = ConfigurationManager.AppSettings["QQAppKey"]; /// <summary> /// 获取oauth信息 /// </summary> /// <param name="code"></param> /// <returns></returns> public QQOauthInfo GetOauthInfo(string code) { string callback = System.Web.HttpUtility.UrlEncode(ConfigurationManager.AppSettings["QQCallBack"], Encoding.UTF8); string url = string.Format("https://graph.qq.com/oauth2.0/token?grant_type={0}&client_id={1}&client_secret={2}&code={3}&redirect_uri={4}", "authorization_code", appID, appKey, code, callback); string res = LoadHtmlUserGetType(url, Encoding.UTF8); QQOauthInfo qqOauthInfo = new QQOauthInfo(); qqOauthInfo.AccessToken = CutString(res, "access_token=", "&expires_in="); qqOauthInfo.ExpiresIn = CutString(res, "&expires_in=", "&refresh_token="); qqOauthInfo.RefreshToken = res.Split(new string[] { "&refresh_token=" }, StringSplitOptions.None)[1]; return qqOauthInfo; } /// <summary> /// 截取字符串中两个字符串中的字符串 /// </summary> /// <param name="str">字符串</param> /// <param name="startStr">开始字符串</param> /// <param name="endStr">结束字符串</param> /// <returns></returns> private string CutString(string str, string startStr, string endStr) { int begin, end; begin = str.IndexOf(startStr, 0) + startStr.Length; //开始位置 end = str.IndexOf(endStr, begin); //结束位置 return str.Substring(begin, end - begin); //取搜索的条数,用结束的位置-开始的位置,并返回 } /// <summary> /// 经过GET方式获取页面的方法 /// </summary> /// <param name="urlString">请求的URL</param> /// <param name="encoding">页面编码</param> /// <returns></returns> public string LoadHtmlUserGetType(string urlString, Encoding encoding) { HttpWebRequest httpWebRequest = null; HttpWebResponse httpWebRespones = null; Stream stream = null; string htmlString = string.Empty; try { httpWebRequest = WebRequest.Create(urlString) as HttpWebRequest; } catch (Exception ex) { throw new Exception("创建页面请求时发生错误!", ex); } httpWebRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; Maxthon 2.0)"; try { httpWebRespones = (HttpWebResponse)httpWebRequest.GetResponse(); stream = httpWebRespones.GetResponseStream(); } catch (Exception ex) { throw new Exception("接受服务器返回页面时发生错误!", ex); } StreamReader streamReader = new StreamReader(stream, encoding); try { htmlString = streamReader.ReadToEnd(); } catch (Exception ex) { throw new Exception("读取页面数据时发生错误!", ex); } streamReader.Close(); stream.Close(); return htmlString; } /// <summary> /// 获取QQ帐号的OpenID /// </summary> /// <param name="qqOauthInfo"></param> /// <returns></returns> public string GetOpenID(QQOauthInfo qqOauthInfo) { string res = LoadHtmlUserGetType("https://graph.qq.com/oauth2.0/me?access_token=" + qqOauthInfo.AccessToken, Encoding.UTF8); return CutString(res, @"openid"":""", @"""}"); } /// <summary> /// 获取QQ昵称 /// </summary> /// <param name="qqOauthInfo"></param> /// <param name="openID"></param> /// <returns></returns> public string GetUserInfo(QQOauthInfo qqOauthInfo, string openID) { string urlGetInfo = string.Format(@"https://graph.qq.com/user/get_user_info?access_token={0}&oauth_consumer_key={1}&openid={2}", qqOauthInfo.AccessToken,appID, openID); string resUserInfo = LoadHtmlUserGetType(urlGetInfo, Encoding.UTF8); return CutString(resUserInfo, @"""nickname"": """, @""","); } } public class QQOauthInfo { public string AccessToken { get; set; } public string ExpiresIn { get; set; } public string RefreshToken { get; set; } } }
四.Demo效果
你们能够直接访问http://www.mylanqiu.com看一下实际的效果,最后感谢你们的阅读,如对你有所帮助就多多转发,以帮助更多人,正所谓:赠人玫瑰 手有余香!若有不足,还请指正!