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();
        }

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

时间: 2024-07-29 05:54:00

ASP.NET MVC 支持微信OpenId登陆的相关文章

ASP.NET MVC 接入微信公共平台

ASP.NET MVC 接入微信公共平台 申请微信公共账号 既然要接入微信公共平台,微信公共号是必须的(当然如果只是测试的话也可以申请微信公共平台接口测试账号),来这里微信公共平台 申请微信公共号(注:申请微信公共号不能用已绑定微信的邮箱),微信公共平台有自己的官方文档,官方文档有不少资料,可以多看看,开发者模式默认是关闭的,需要配置并启用,如下图: URL即你的网站处理微信模块,必须是HTTP://开头的网站,笔者自己之前接入几天一直失败,最终发现是因为自己网站加密了用的是HTTPS,这个需要

微信开发】【Asp.net MVC】-- 微信分享功能

[微信开发][Asp.net MVC]-- 微信分享功能 2017-01-15 09:09 by stoneniqiu, 12886 阅读, 15 评论, 收藏, 编辑 内嵌在微信中的网页,右上角都会有一个默认的分享功能.如下图所示,第一个为自定义的效果,第二个为默认的效果.实现了自定义的分享链接是不是更让人有点击的欲望?下面讲解下开发的过程. 一.准备,设置js接口安全域名 这需要使用微信的jssdk,先需要在微信公众号后台进行设置:公众号设置-->功能设置-->JS接口安全域名.打开这个页

让 asp.net mvc 支持 带有+ _ 等特殊字符的路由

最近配置微信 业务域名 时,需要在服务器的根目录中上传一个文本文件,而这个文本文件需要放这样的目录中: 于在就在 服务器目录中创建了对应的文件夹,并将kuPv.txt上传,但是访问时,却怎么也访问不到.原来ASP.NET 默认是不支持带有特殊符号的路径的, 如果需要支持,需要在web.config中配置此项:如下 <configuration> <system.webServer> <security> <requestFiltering allowDoubleE

asp.net mvc内微信pc端、H5、JsApi支付方式总结

转自:http://www.80cxy.com/Blog/ArticleView?arId=201912122203555530g0wwI8 本文提供技术支持QQ:806693619   V:kwstugdb 微信提供了各种支付方式,有针对手机APP开发的支付方式,有针对pc web端的,手机端的等,pc端支付使用场景是在pc端完整内使用的支付方式,JsApi只能在微信内被调用,H5不限于微信内使用,手机端浏览器内也可以使用,个人理解的不知道对不对,本文主要介绍pc端.H5.JsApi支付方式,

【微信开发】【Asp.net MVC】-- 微信分享功能

内嵌在微信中的网页,右上角都会有一个默认的分享功能.如下图所示,第一个为自定义的效果,第二个为默认的效果.实现了自定义的分享链接是不是更让人有点击的欲望?下面讲解下开发的过程. 一.准备,设置js接口安全域名 这需要使用微信的jssdk,先需要在微信公众号后台进行设置:公众号设置-->功能设置-->JS接口安全域名.打开这个页面之后你会看到下面的提示.需要先下载这个文件并上传到指定域名的根目录. 这个文件里面是一个字符串,从名称看是用来校验用的.先上传了这个文件,你才能保存成功.这样你就可以使

ASP.NET MVC获取微信返回的json数据分页

View @model JiaYe.WeiXin.Models.ViewModels.UserViewModel <div class="pull-left pagination"> <ul class="pagination pagination-outline"> @{ //分页算法:(总记录数+每页记录数-1)/每页记录数 var totalPageNum = (Model.OpenIdResult.openid.Count + 10

ASP.NET MVC开发微信(一)

public string index(string echostr) { return echostr; }

ASP.NET MVC开发微信(二)

ASP.NET MVC下的四种验证编程方式[续篇]

在<ASP.NET MVC下的四种验证编程方式>一文中我们介绍了ASP.NET MVC支持的四种服务端验证的编程方式("手工验证"."标注ValidationAttribute特性"."让数据类型实现IValidatableObject或者IDataErrorInfo"),那么在ASP.NET MVC框架内部是如何提供针对这四种不同编程方式的支持的呢?接下来我们就来聊聊这背后的故事. 一.ModelValidator与ModelVal