現(xiàn)在QQ第三方快捷登錄在網(wǎng)站/App中的應(yīng)用已經(jīng)非常普遍,QQ快捷登錄不僅可以減少用戶(hù)登錄、注冊(cè)平臺(tái)所花費(fèi)的時(shí)間,而且不需要牢記平臺(tái)賬戶(hù)密碼,對(duì)于提升用戶(hù)體驗(yàn)可謂是錦上添花(注:本人是記不住任何網(wǎng)站賬號(hào)密碼的)。


當(dāng)然,有很多站點(diǎn)沒(méi)有使用任何第三方登錄功能,這里不做過(guò)多評(píng)價(jià)。


下面看下C#中如何實(shí)現(xiàn)QQ一鍵登錄功能 沒(méi)有引用任何第三方封裝的幫助類(lèi)庫(kù),全部源碼開(kāi)放,結(jié)尾處有DEMO案例,請(qǐng)自行下載。


第一步:請(qǐng)自行到QQ互聯(lián)(https://connect.qq.com)申請(qǐng)開(kāi)發(fā)者權(quán)限,創(chuàng)建屬于自己網(wǎng)站的應(yīng)用

對(duì)于這一步 這里不做過(guò)多敘述,進(jìn)入QQ互聯(lián)按照步驟填寫(xiě)資料后 等待審核就行。



第二步:這里視作第一步已經(jīng)完成 并取得了APP ID 和 APP Key并已配置好網(wǎng)站回調(diào)地址,廢話不多說(shuō) 直接上代碼來(lái)看。

下面為QQ互聯(lián)交互處理幫助類(lèi),請(qǐng)自行換成自己的ID和Key。

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.Specialized;
using System.Configuration;
using System.Web;
using System.Web.Script.Serialization;
using System.Text.RegularExpressions;
namespace OAuthQQ.open
{
    /// <summary>
    /// C#實(shí)現(xiàn)QQ快捷登錄網(wǎng)站DEMO
    /// 來(lái)源:hnxxbl.cn
    /// </summary>
    public sealed class QQLogin
    {
        private const string AppId = "xxxxx";//QQ互聯(lián)中申請(qǐng)的APPID
        private const string AppKey = "xxxxxxxx";//QQ互聯(lián)中申請(qǐng)的APP Key
        private const string RequestAuthorizeUrl = "https://graph.qq.com/oauth2.0/authorize";
        private const string RequestAccessTokenUrl = "https://graph.qq.com/oauth2.0/token";
        private const string RequestOpenIdUrl = "https://graph.qq.com/oauth2.0/me";
        private const string RequestUserInfoUrl = "https://graph.qq.com/user/get_user_info";
        public static string getLoginUrl(string state)
        {
            return RequestAuthorizeUrl   "?response_type=code&client_id="   AppId   "&redirect_uri="   getCallBackUrl()   "&state="   state;
        }
        public static string getCallBackUrl()
        {
            return HttpUtility.UrlEncode("http://www.xxxxxx.com/open/open.aspx");//此處鏈接務(wù)必修改為自己網(wǎng)站對(duì)應(yīng)鏈接
        }
        private string getTokenUrl(string code)
        {
            string ret = Utils.httpGet(RequestAccessTokenUrl   "?grant_type=authorization_code&client_id="   AppId   "&client_secret="   AppKey   "&code="   code   "&redirect_uri="   getCallBackUrl());
            return HttpUtility.ParseQueryString(ret).Get("access_token");
        }
        private QQOpenIdInfo getOpenId(string accessToken)
        {
            string ret = Utils.httpGet(RequestOpenIdUrl   "?access_token="   accessToken);
            if (!ret.StartsWith("callback"))
            {
                return null;
            }
            JavaScriptSerializer jss = new JavaScriptSerializer();
            int start = ret.IndexOf("(")   1;
            int end = ret.IndexOf(")");
            return jss.Deserialize<QQOpenIdInfo>(ret.Substring(start, end - start));
        }
        private QQUserInfo getUserInfo(string access_token, string openId)
        {
            string ret = Utils.httpGet(RequestUserInfoUrl   "?access_token="   access_token   "&oauth_consumer_key="   AppId   "&openid="   openId);
            JavaScriptSerializer jss = new JavaScriptSerializer();
            return jss.Deserialize<QQUserInfo>(ret);
        }
        public OpenInfo login(string code)
        {
            OpenInfo info = new OpenInfo();
            try
            {
                string accessToken = getTokenUrl(code);
                QQOpenIdInfo qqOpenIdInfo = getOpenId(accessToken);
                if (qqOpenIdInfo == null)
                {
                    return null;
                }
                QQUserInfo userInfo = getUserInfo(accessToken, qqOpenIdInfo.OpenId);
                info.OpenId = qqOpenIdInfo.OpenId;
                info.NickName = userInfo.NickName;
                info.Photo = userInfo.Figureurl_1;
            }
            catch (Exception e)
            {
                info.ErrorMsg = e.ToString();
                info.HasError = false;
            }
            return info;
        }
    }
}
下面來(lái)看下交互處理調(diào)用方法(當(dāng)然還有一些其他輔助類(lèi),這里不做過(guò)多解釋?zhuān)?qǐng)下載源碼附件自行查看)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace OAuthQQ.open
{
    /// <summary>
    /// 首頁(yè) 運(yùn)行此頁(yè)面跳轉(zhuǎn)測(cè)試(為保證測(cè)試效果,請(qǐng)務(wù)必在配置完整后在公網(wǎng)環(huán)境進(jìn)行)
    /// 來(lái)源:hnxxbl.cn
    /// </summary>
    public partial class qq : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            string state = Utils.getRandomNumber().ToString();
            HttpCookie loginCookie = new HttpCookie("OAuthQQLogin", state);
            Response.Cookies.Add(loginCookie);
            Response.Redirect(QQLogin.getLoginUrl(state));
        }
    }
}

第三步:進(jìn)行回調(diào)地址頁(yè)面邏輯編寫(xiě),代碼已奉上 請(qǐng)查閱
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace OAuthQQ.open
{
    /// <summary>
    /// 此頁(yè)面為登錄成功后的回調(diào)地址,此頁(yè)面地址需要在QQ互聯(lián)接口基本信息中預(yù)先配置,否則無(wú)法使用
    /// 來(lái)源:hnxxbl.cn
    /// </summary>
    public partial class open : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            string state = Request.QueryString["state"];
            string code = Request.QueryString["code"];
            if (code == null)
            {
                //參數(shù)不全不處理請(qǐng)求 ,跳轉(zhuǎn)到首頁(yè)
                Response.Redirect("http://www.xxxxxx.com/");
            }
            OpenInfo info = null;//當(dāng)前登錄用戶(hù)信息
            HttpCookie cookie = Request.Cookies["OAuthQQLogin"];
            //qq登錄
            if (cookie.Value == state)
            {
                QQLogin qqLogin = new QQLogin();
                info = qqLogin.login(code);
            }
            if (info.HasError)
            {
                //出錯(cuò)
                Response.Write("出錯(cuò)"   Server.UrlEncode(info.ErrorMsg));
            }
            //至此 若info!=null 并且OpenId不為空,則登錄成功
            if (info != null && !string.IsNullOrEmpty(info.OpenId))
            {
                //登錄成功,獲取用戶(hù)信息
                //請(qǐng)?jiān)诖颂幚砟牡卿?注冊(cè)業(yè)務(wù)邏輯
                string query = "photo="   info.Photo   "&nickname="   info.NickName   "&openid="   info.OpenId;
                Response.Write(query);
            }
        }
    }
}

第四步:說(shuō)那么多廢話,其實(shí)以上代碼只需要配置AppID 、APPKey、回調(diào)地址即可。其他登錄、注冊(cè)邏輯請(qǐng)自行處理。

完成以上代碼配置后,就可以進(jìn)行線上測(cè)試,為保證測(cè)試效果,請(qǐng)務(wù)必在配置完整后在公網(wǎng)環(huán)境進(jìn)行。如有疑問(wèn) 請(qǐng)進(jìn)入技術(shù)群咨詢(xún)?nèi)褐鳌?/span>


第五步:第五步已經(jīng)沒(méi)啥能說(shuō)的了,下面來(lái)看下源碼目錄結(jié)構(gòu)。




點(diǎn)擊下載 C#實(shí)現(xiàn)QQ快捷登錄注冊(cè)案例源碼 回家自行研究吧。看我說(shuō)的再多,不如自己去實(shí)戰(zhàn)下來(lái)的爽快。



原文鏈接:C#實(shí)現(xiàn)QQ快捷登錄注冊(cè)案例