首页 > 代码库 > ASP.NET MVC 支持微信OpenId登陆

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 =http://www.mamicode.com/ 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();        }

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

 

ASP.NET MVC 支持微信OpenId登陆