ASP.Net 微信H5 OAuth2 认证 (前后端不分离)

在19年出开始接触微信的开发,OAuth认证是我遇到的第一个难题。边学习边记录

首先在微信公众平台配置网页授权域名

 

 

 

需要用到的DLL

Senparc.Weixin.dll

Senparc.Weixin.MP.dll

Senparc.Weixin.WxOpen.dll

 

首先创建一个身份认证的特性 放在所有Controller里面

 

OAuth2AuthorizeAttribute.cs  代码如下

public class OAuth2AuthorizeAttribute : AuthorizeAttribute
    {
        /// <summary>
        /// 验证是否已存用户的wxopenid
        /// </summary>
        /// <param name="filterContext"></param>
        public override void OnAuthorization(AuthorizationContext filterContext)
        {

            try
            {
                var request = filterContext.HttpContext.Request;//获取http请求
                
                var req = filterContext.HttpContext.Request.RawUrl.ToString();//拿到完整url

var d = HttpContext.Current.Request.Url.ToString();//这个也是拿到完整的url 只不过这个可以拿到路由里面的参数 上面则不可以 Common.Logs._StrUrl = d;//存到一个常量里面 //判断cookie里面有没有存这个用户的wxopenid if (string.IsNullOrWhiteSpace(TUser.GetUserOpenId())) { //如果cookie里面没有用户的wxopenid则重定向 filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "OAuth2", action = "index", strurl = Common.Logs._StrUrl, })); } } catch (Exception ex) { } } }

 

TUser.cs 

 public static class TUser
    {
        #region 变量区域

        #region Cookie Keys
        /// <summary>
        /// UserPwd Cookie Key
        /// </summary>
        public static string UserOpenIdKey = "577355724964";

        /// <summary>
        /// ValueExt
        /// </summary>
        public static string ValueExt = "_isoks";


        /// <summary>
        /// CookieName
        /// </summary>
        public static string CookieName = "596f727a696b752e576562";


        #endregion

        #endregion

        #region+GetUserOpenId 获取UserOpenId

        public static string GetUserOpenId()
        {
            try
            {
                var cookie = GetCookie();
                if (cookie == null) return string.Empty;
                var userOpenId = cookie.Values[UserOpenIdKey];
                return userOpenId;
            }
            catch
            {
                return string.Empty;
            }
            return string.Empty;
        }

        #endregion

        #region +SetCookie 设置登录的cookie
        /// <summary>
        /// 设置登录的cookie
        /// </summary>
        /// <param name="id">id</param>
        /// <param name="name">用户名</param>
        public static void SetUserOpenId(string userOpenId)
        {
            var cookie = new HttpCookie(CookieName) { HttpOnly = true };
            cookie.Values.Add(UserOpenIdKey, userOpenId);
            //cookie.Expires = DateTime.Now.AddDays(30);
            HttpContext.Current.Response.SetCookie(cookie);
        }
        #endregion

        #region +GetCookie 获取Cookie实例 
        /// <summary>
        /// 获取Cookie实例
        /// </summary>
        /// <returns></returns>
        public static HttpCookie GetCookie()
        {
            try
            {
                var key = CookieName;
                var cookie = HttpContext.Current.Request.Cookies[key];
                return cookie;
            }
            catch
            {
                return null;
            }
        }
        #endregion

    }

 

 

OAuth2Controller 代码 

 /// <summary>
    /// 调用微信API换取WXOpenid
    /// </summary>
    public class OAuth2Controller : BaseController
    {
        /// <summary>
        /// 定义一个常量用来存储需要请求的路径
        /// </summary>
        public static string PrevUrl = string.Empty;
        public ActionResult Index(string strurl = "")
        {
            //给常量赋值
            PrevUrl = strurl;
            //调用微信API接口 BAPPID=公众号的APPID  BREDIRECTURL=接收微信返回结果的路由 例:http://localhost/OAuth2/RedirectUrl
            var uri = OAuthApi.GetAuthorizeUrl(BAPPID, BREDIRECTURL, "0", OAuthScope.snsapi_userinfo);
            //重定向访问微信授权地址
            return Redirect(uri);
        }

        /// <summary>
        /// 微信OAuthApi回调
        /// </summary>
        /// <param name="code">状态码</param>
        /// <param name="state"></param>
        /// <returns></returns>
        public ActionResult RedirectUrl(string code, string state)
        {
            try
            {
                //判断状态码是否为空
                if (string.IsNullOrEmpty(code))
                {
                    return Json(new { State = false, Msg = "哎呀,出错了!" });
                }
              
                //定义一个接收Tokoen的result
                OAuthAccessTokenResult result = null;
                try
                {
                    result = OAuthApi.GetAccessToken(BAPPID, BSECRET, code);
                }
                catch (Exception ex)
                {
                    return Json(new { State = false, Msg = "哎呀,出错了!" });
                }
                if (result.errcode != ReturnCode.请求成功)
                {
                    return Json(new { State = false, Msg = "哎呀,出错了!" });
                }


                //拿到token以后调用微信接口 用token和openid换去用户信息
                var userinfo = OAuthApi.GetUserInfo(result.access_token, result.openid);
                //拿到用户信息后创建或修改自己项目中的用户表
                if (userinfo != null)
                {
                    var user = UserRepository.GetUserByWxOpenId(result.openid);
                    if (user != null)
                    {
                        user.NickName = userinfo.nickname;
                        user.HeadImg = userinfo.headimgurl;
                        user.UserSex = (UserSex)Enum.Parse(typeof(UserSex), userinfo.sex.ToString());
                        UserRepository.SaveOrUpdate(user);
                    }
                    else
                    {
                        //create user
                        User guser = new User();
                        guser.WxOpenId = result.openid;
                        guser.HeadImg = userinfo.headimgurl;
                        guser.NickName = userinfo.nickname;
                        guser.State = true;
                        guser.UserSex = (UserSex)Enum.Parse(typeof(UserSex), userinfo.sex.ToString());
                        guser.AddTime = DateTime.Now;
                        guser.UserType = UserType.游客;
                        guser.GuId = Guid.NewGuid().ToString();
                        UserRepository.SaveOrUpdate(guser);
                    }
                }
                //将用户的openid存起来
                TUser.SetUserOpenId(result.openid);
                //跳转程序原来要跳转的路由
                if (IsoksIsNullOrWhiteSpace(PrevUrl))
                {
                    return Redirect(PrevUrl);
                }
                return Redirect("~/home/index");
            }
            catch (Exception ex)
            {
                log(ex.Message, "出错啦");
            }
            return Error500cshtml();
        }
    }

 

 

总体思路:客户端发来请求,通过过滤器拿到要请求的路径,判断cookie里面有没有存当前用户的wxopenid,如果存了直接跳转正常要请求的路径,如果wxopenid为空 则重定向到OAuth2Controll 根据配置的APPID和BREDIRECTURL=重定向url跟微信API进行交互获取用户的微信信息进行创建或更新用户并在cookie里面存储用户信息

 

posted @ 2021-12-28 17:17  吃兔子的萝卜7  阅读(348)  评论(1编辑  收藏  举报