欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ASP.NET MVC 支持微信OpenId登陆

程序员文章站 2023-12-28 20:36:10
...

  之前微信的网站都是使用的是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();
        }

    大功告成,这种方式感觉还是有点儿不好,如果有做过类似功能的朋友,还请指点一下有没有其他的实现方式,谢谢大家。

 

上一篇:

下一篇: