ASP.NET MVC 支持微信OpenId登陸


  之前微信的網站都是使用的是identity來做用戶登錄的,用戶都是要每次輸入用戶賬號和密碼。然后identity把用戶信息保存在本地一段時間。現在是需要當用戶在登錄的時候綁定當前的微信賬戶的OpenId,通過OpenId來獲取用戶信息實現自動登錄。

  在用戶進入Login這個Action之前,獲取到OpenId,判斷該OpenId是否綁定用戶信息,如果綁定則自動登陸,並返回redirectUrl。否則把OpenId保存到Cookie,然后跳轉到LoginAction,在登錄驗證成功之后把OpenId綁定到該用戶信息上。繼承實現AuthorizeAttribute,

  

    public class WXFilterAttribute : AuthorizeAttribute
    {
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            string userAgent = httpContext.Request.UserAgent;
            if (userAgent.IndexOf("MicroMessenger") <= -1)//不是微信瀏覽器
            {
                return true;
            }
             
            if (!httpContext.User.Identity.IsAuthenticated)
            {
                ApplicationSignInManager SignInManager = httpContext.GetOwinContext().Get<ApplicationSignInManager>();
                ApplicationUserManager UserManager = httpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
                string appid = string.Empty;
                string secret = string.Empty;

                
                appid = WxPayConfig.APPID;
                secret = WxPayConfig.APPSECRET;

                var code = httpContext.Request["Code"];
                string returnUrl = HttpUtility.UrlDecode(httpContext.Request["ReturnUrl"] ?? "/");


                if (string.IsNullOrEmpty(code))
                {                    
                    string host = httpContext.Request.Url.Host;
                    string path = httpContext.Request.Path;
                    string redirectUrl = "http://" + host + path + "?ReturnUrl=" + HttpUtility.UrlEncode(returnUrl);//重定向的url,這里不需要進行編碼,在后面會自己編碼
                    try
                    {
                        //todo:通過微信獲取2.0授權的url
                        string url = GetAuthorizeUrl(appid, redirectUrl, "state", "snsapi_base");
                        
                        httpContext.Response.Redirect(url);
                    }
                    catch (System.Exception ex)
                    {
#if DEBUG
                        httpContext.Response.Write("構造網頁授權獲取code的URL時出錯,錯誤是:" + ex.Message);
                        httpContext.Response.End(); 
#endif
                    }
                }
                else
                {
                    var client = new System.Net.WebClient();
                    client.Encoding = System.Text.Encoding.UTF8;
                    string url = GetAccessTokenUrl(appid, secret, code);
                    var data = client.DownloadString(url);
                    var obj = JsonConvert.DeserializeObject<Dictionary<string, string>>(data);
                    string accessToken;
                    if (!obj.TryGetValue("access_token", out accessToken))
                    {
#if DEBUG
                        httpContext.Response.Write("構造網頁授權獲取access_token的URL時出錯");
                        httpContext.Response.End();
#endif
                    }
                    var openid = obj["openid"];
                    Utils.WidgetCode.ServerInfo.SetCookies("WXopenid", openid, DateTime.MinValue);
                    
                    var existUser = UserManager.Users.FirstOrDefault(p => p.OpenId == openid);
                    if (existUser != null)
                    {
                        SignInManager.SignInAsync(existUser, false, false);
                        httpContext.Response.Redirect(returnUrl);
                    }
                }
            }
            return true;
        }
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);
            if (filterContext.HttpContext.Response.StatusCode == 401)
            {
                filterContext.Result = new RedirectResult("/403.htm");//跳轉異常頁面
            }
        }

        //擴展
        public string GetAuthorizeUrl(string appId, string redirectUrl, string state, string scope, string responseType = "code")
        {
            if (!string.IsNullOrEmpty(redirectUrl))
            {
                redirectUrl = HttpUtility.UrlEncode(redirectUrl, System.Text.Encoding.UTF8);
            }
            else
            {
                redirectUrl = null;
            }
            object[] args = new object[] { appId, redirectUrl, responseType, scope, state };
            return string.Format("https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type={2}&scope={3}&state={4}#wechat_redirect", args);
        }
        public string GetAccessTokenUrl(string appId, string secret, string code, string grantType = "authorization_code")
        {
            object[] args = new object[] { appId, secret, code, grantType };
            string requestUri = string.Format("https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type={3}", args);
            //return GetAccessTokenInfo(_httpClient.GetAsync(requestUri).Result.Content.ReadAsStringAsync().Result);
            return requestUri;
        }
    }

  然后在LoginAction上添加Attribute

  

        [WXFilterAttribute]
        public ActionResult Login()
        {

            return View();
        }

    大功告成,這種方式感覺還是有點兒不好,如果有做過類似功能的朋友,還請指點一下有沒有其他的實現方式,謝謝大家。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM