最近在作一個項目時,客戶要求網站可以集成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看一下實際的效果,最後感謝你們的閱讀,如對你有所幫助就多多轉發,以幫助更多人,正所謂:贈人玫瑰 手有餘香!若有不足,還請指正!