ASP.NET MVC應用程序中支持用戶使用騰訊QQ和微信以及新浪微博的第三方登陸

什麼是第三方受權登陸,就是一些你們都會有的賬號如QQ、微信、淘寶、微博等帳戶。經過那些巨頭公司提供的api直接實現登陸。

固然,咱們是不可能獲得你的用戶名和密碼的。不瞭解的人,可能會存在這個疑慮。咱們能夠經過第三方受權登陸獲得如暱稱、性別、註冊地址、年齡、頭像等基本信息。固然,咱們也能夠獲得你帳戶由於的惟一編碼,就是OAuthId。什麼是OAuth技術?你們自行了解,這裏就不細講了。git

準備資料:github

各平臺相關受權appid以及appkey(新浪爲App Secret)api

申請地址:瀏覽器

新浪服務器

    申請入口  http://open.weibo.com/connect微信

    開發文檔 http://open.weibo.com/wiki/%E7%BD%91%E7%AB%99%E6%8E%A5%E5%85%A5cookie

騰訊QQapp

   申請入口:http://connect.qq.com/ide

   開發文檔  http://wiki.connect.qq.com/ui

微信 

    申請入口https://open.weixin.qq.com/

    開發文檔 https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&lang=zh_CN

以QQ爲例:

從以上文檔中能夠得知,得到openId以及QQ得到用戶信息須要三步,第一步,封裝請求連接,而後服務的返回瀏覽器302跳轉至微信或QQ等用戶受權窗口

 public ActionResult QQLogin(string returnUrl)
        {
            AuthenticationScope scope=new AuthenticationScope(){
                State=Guid.NewGuid().ToString().Replace("-", ""),
                Scope="get_user_info"
            };
            if (!string.IsNullOrEmpty(returnUrl))
            {
                Session["returnUrl"] = returnUrl;
            }
            Session["requeststate"] = scope.State;
            string url=_tencentHandler.GetAuthorizationUrl(scope);
            return Redirect(url);
        }

 

 public override string GetAuthorizationUrl(AuthenticationScope scope)
        {
            string url = string.Empty;
            if (string.IsNullOrEmpty(scope.Scope))
            {
                url = string.Format("{0}/oauth2.0/authorize?response_type=code&client_id={1}&redirect_uri={2}&state={3}", _options.AuthorizeUrl, _options.AppId, string.Concat(_options.Host, _options.Callback), scope.State);
            }
            else
            {
                url = string.Format("{0}/oauth2.0/authorize?response_type=code&client_id={1}&redirect_uri={2}&state={3}&scope={4}", _options.AuthorizeUrl, _options.AppId, Uri.EscapeDataString(string.Concat(_options.Host, _options.Callback)), scope.State, scope.Scope);
            }
            return url;
        }

 

 成功後瀏覽器會跳轉至

redirect_uri傳遞的連接窗口即QQOAuthController下面的CallBack

public ActionResult CallBack()
{
var verifier = Request.Params["code"];
string state = Session["requeststate"].ToString();
QQAuthenticationTicket ticket = new QQAuthenticationTicket()
{
Code=verifier,
Tag = "Tencent.QQ"
};
ticket = _tencentHandler.PreAuthorization(ticket);
ticket = _tencentHandler.AuthenticateCore(ticket);
UserClaim userClaim = getUserClaimByOpenIdOrUnionId(ticket.OpenId, "", ticket.Tag);
if (userClaim != null)
{
FormsAuthentication.SetAuthCookie(userClaim.User.UserName, true);
if (Session["returnUrl"] != null && string.IsNullOrEmpty(Session["returnUrl"].ToString()))
{
return Redirect(Session["returnUrl"].ToString());
}
return RedirectToAction("Index", "Home");
}
SocialUser user = _tencentHandler.GetUserInfo(ticket);
Session["social.current"] = user;
return RedirectToAction("social", "members");
}

這方法的主要做用是依據返回的code,與Authorization Server即(QQ或者微博)進行受權認證,獲取token,依據token獲取openId以及微信的unionId等張華信息

 public override QQAuthenticationTicket PreAuthorization(QQAuthenticationTicket ticket)
        {
            string tokenEndpoint = string.Concat(_options.AuthorizeUrl, "/oauth2.0/token?grant_type=authorization_code&client_id={0}&client_secret={1}&code={2}&redirect_uri={3}");
            var url = string.Format(
                     tokenEndpoint,
                     Uri.EscapeDataString(_options.AppId),
                     Uri.EscapeDataString(_options.AppSecret),
                     Uri.EscapeDataString(ticket.Code), Uri.EscapeDataString(string.Concat(_options.Host, _options.Callback)));
            string tokenResponse = _httpClient.GetStringAsync(url).Result.ToString();
            if (tokenResponse.IndexOf('&') > 0)
            {
                var parameters = tokenResponse.Split('&');
                foreach (var parameter in parameters)
                {
                    var accessTokens = parameter.Split('=');
                    if (accessTokens[0] == "access_token")
                    {
                        ticket.AccessToken = accessTokens[1];
                    }
                    else if (accessTokens[0] == "refresh_token") 
                    {
                        ticket.RefreshToken = accessTokens[1];
                    }
                    
                }
            }
            return ticket;
        }
 public override QQAuthenticationTicket AuthenticateCore(QQAuthenticationTicket ticket)
        {
            string tokenEndpoint = string.Concat(_options.AuthorizeUrl, "/oauth2.0/me?access_token={0}");
            var url = string.Format(
                     tokenEndpoint,ticket.AccessToken);
            string tokenResponse = _httpClient.GetStringAsync(url).Result.ToString();
            string strJson = tokenResponse.Replace("callback(", "").Replace(");", "");
            var payload = JsonHelper.DeserializeObject<Callback>(strJson);
            ticket.OpenId=payload.openid;
            return ticket;
        }

執行到這裏時應該已經獲取到openId以及token等相關信息,在自身服務器的用戶管理中查找這個帳戶的綁定記錄,若是有相關信息依據取出的相關信息進行用戶受權寫入cookie或者其餘操做,如無調用Authorization Server的相關接口獲取相關信息,用QQ的暱稱頭像,新浪微博貌似沒法獲取相關信息

protected UserClaim getUserClaimByOpenIdOrUnionId(string openId, string unionId, string tag)
{
UserClaim claim = MembershipService.GetExtendSocialByOpenId(openId, tag);
if (claim != null)
{
return claim;
}
return MembershipService.GetExtentSocialByUnionId(unionId, tag);
}
UserClaim爲第三方帳戶的相關信息類
 public class UserClaim
    {
        /// <summary>
        /// 用戶Id
        /// </summary>
        public int Id { get; set; }
        /// <summary>
        /// 用戶Id
        /// </summary>
        public int UserId { get; set; }
        /// <summary>
        /// 用戶認證類型
        /// </summary>
        public string Tag { get; set; }
        /// <summary>
        /// OpenId
        /// </summary>
        public string OpenId { get; set; }
        /// <summary>
        /// UnionId
        /// </summary>
        public string UnionId { get; set; }
        /// <summary>
        /// Token
        /// </summary>
        public string Token { get; set; }
        /// <summary>
        /// RefreshToken
        /// </summary>
        public string RefreshKey { get; set; }
        public virtual MembershipUser User { get; set; }
        
    }

 

其餘相似最後附上相關代碼https://github.com/491134648/Farmer.Social
相關文章
相關標籤/搜索