zoukankan      html  css  js  c++  java
  • .netMVC企业微信网页授权+注册全局过滤器

    微信网页授权

      达到效果:企业应用只能在微信中查看,在浏览器中打开企业页面,显示无权限!

    原理,用session记录用户,如果用户已经通过微信授权,记录@Session["UserId"],如果用户没有登录,则采用微信页面跳转的Code去换取UserId,如果能成功换取,则存入session,并登录成功。

    逻辑图如下:

      (小插曲:1 微信页面重定向时,会发送多个请求,导致只能使用一次的Code失效 40029 报错

        处理逻辑是,采用同步锁,页面第一次跳转到我们的服务器时,把code存入session,并且对这段代码加锁,如果微信又发一个请求,先对比session中的Code,如果有了,则不再使用第二个code(因为微信页面授权code只能使用一次))

      
          private static object locker = new object(); //同步锁
          try
    { lock (locker) { if (Session["UserId"] == null)// 1 如果用户未登录 { if (!string.IsNullOrWhiteSpace(code) && Session["Code"] != (object)code)//2 有Code 参数,并且Code参数是第一次 { //处理逻辑Star Session["Code"] = code;//把Code记录session var userid = WechatCheckCode(code).UserId; //调用微信接口,获取用户信息 if (string.IsNullOrWhiteSpace(userid)) { response.Redirect("/Admin/Admin/Error?msg=xxxxxx"); } Session["UserId"] = userid;//用户写入session //处理逻辑End } else { response.Redirect("/Admin/Admin/Error?msg=xxxxxx"); } } } } catch { response.Redirect("/Admin/Admin/Error?msg=xxxxxx"); }

      (小插曲:2 为了让所有的Controller都先进行一次校验,采用全局过滤器)

    // 1在Global中添加全局过滤器
    GlobalFilters.Filters.Add(new AuthAttribute());
    
    //2 AuthAttribute 过滤器逻辑
     public class AuthAttribute : AuthorizeAttribute
        {
            private readonly string WeChatUrl = ConfigurationManager.AppSettings["WeChatUrl"];
            private static object locker = new object();//使用同步锁,防止微信一次跳转多次请求
            public override void OnAuthorization(AuthorizationContext filterContext)
            {
                var path = filterContext.HttpContext.Request.Path;
                if (!path.ToLower().StartsWith("/admin/admin/error"))
                {
                    var response = filterContext.HttpContext.Response;
                    var request = filterContext.HttpContext.Request;
                    var Session = filterContext.HttpContext.Session;
                    var code = request.Params["code"];
    
                    try
                    {
                        lock (locker)
                        {
                            if (Session["UserId"] == null)
                            {
                                if (!string.IsNullOrWhiteSpace(code) && Session["Code"] != (object)code)//1 判断session里面是否有用户
                                {
                                    Session["Code"] = code;
                                    var userid = WechatCheckCode(code).UserId;
                                    if (string.IsNullOrWhiteSpace(userid))
                                    {
                                        response.Redirect("/Admin/Admin/Error?msg=xxxxxx");
                                    }
                                    Session["UserId"] = userid;
                                }
                                else
                                {
                                    response.Redirect("/Admin/Admin/Error?msg=xxxxxx");
                                }
                            }
                        }
                    }
                    catch
                    {
                        response.Redirect("/Admin/Admin/Error?msg=xxxxxx");
                    }
                }
            }
            //微信检查Code
            private Wechat_UserModel WechatCheckCode(string code)
            {
                Wechat_UserModel resultBack = null;
                string WeChat_Address = WeChatUrl;
                var url = WeChat_Address + "api/ApiGetUser/GetUser?code=" + code;
                var client = new HttpClient();
                var result = client.GetAsync(url).Result;
                if (result.IsSuccessStatusCode)
                {
                    LogManager.WriteLog("code日志", string.Format("【获取的用户数据】:{0}", result.Content.ReadAsStringAsync().Result));
                    var json = result.Content.ReadAsStringAsync().Result;
                    resultBack = JsonConvert.DeserializeObject<Wechat_UserModel>(json);//Json 反序列化成对象
                }
                return resultBack;
            }

      (小插曲:3 webApi,返回动态Json字符串是,不能直接返回string,应该 返回 HttpResponseMessage

        // 1 微信网页授权根据Code,获取用户信息
            public HttpResponseMessage GetUser(string code)
            {
                string access_token = wxAccess_token.IsExistAccess_Token(wxEnum.供应商系统); //获取access_token
                var json = UserAdminAPI.GetWebUser(access_token, code);//调用微信接口,返回用户JSon字符串
                return new HttpResponseMessage()
                {
                    Content = new StringContent(json, Encoding.UTF8, "application/json")
                };
            }
         /// <summary>
            /// 2 根据code获取成员信息
            /// </summary>
            /// <returns></returns>
            public static string GetWebUser(string access_token, string code)
            {
                var url = string.Format("https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token={0}&code={1}", access_token, code);
                var client = new HttpClient();
                var result = client.GetAsync(url).Result;
                if (!result.IsSuccessStatusCode) return null;
                return result.Content.ReadAsStringAsync().Result;
            }
    
    
    
     

    4 前端页面资源

    效果图:

    1 母版页 @RenderBody()子页面插入的位置,@RenderSection,子页面自定义填充位置
    @{
        Layout = null;
    }
    
    <!doctype html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>供应商移动端</title>
        <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0">
        <link rel="stylesheet" href="~/Content/style/weui.css" />
        <link rel="stylesheet" href="~/Content/style/weui2.css" />
        <link rel="stylesheet" href="~/Content/style/weui3.css" />
        <script src="~/Content/zepto.min.js"></script>
        @RenderSection("Head", required: false)
    </head>
    <body ontouchstart style="background-color: #f8f8f8;">
        
        <div class="weui_tab tab-bottom">
        </div>
        <div class="weui_tabbar ">
            <a href="/admin/admin/Index_mobile" class="weui_tabbar_item weui_bar_item_on">
                <div class="weui_tabbar_icon">
                    <img src="~/Content/images/icon_nav_button.png" alt="">
                </div>
                <p class="weui_tabbar_label">首页</p>
            </a>
        </div>
        @RenderBody() //子页面插入的地方
        @RenderSection("Dialog", required: false)
    </body>
    </html>
    @RenderSection("Foot", required: false)
    
    
    2 首页
    @{
        ViewBag.Title = "Index_mobile";
        Layout = "~/Views/Shared/_LayMobile.cshtml";
    }
    
    <div class="page-hd">
        <h1 class="page-hd-title">
            供应商系统
        </h1>
        <p class="page-hd-desc">用户:@Session["UserId"]</p>
    </div>
    
    <div class="weui_grids">
        <a href="/admin/Reconciliations/Index" class="weui_grid js_grid">
            <div class="weui_grid_icon">
                <img src="~/Content/images/icon_nav_dialog.png" alt="">
            </div>
            <p class="weui_grid_label">
                供应商对账
            </p>
        </a>
        <a href="/admin/Purchase/Index" class="weui_grid js_grid">
            <div class="weui_grid_icon">
                <img src="~/Content/images/icon_nav_cell.png" alt="">
            </div>
            <p class="weui_grid_label">
                采购单查询
            </p>
        </a>
    </div>
    @section Foot{
        <script>    
            Zepto(function ($) {
                //$.ajax({
                //    type: 'POST',
                //    url: 'WechatLogin',
                //    dataType: 'json',
                //    success: function (data) {
                //        alert(data.msg);
                //        console.log(data);
                //    },
                //    error: function (xhr, type) {
                //        alert('Ajax error!')
                //    }
                //})
            })
        </script>
    }
  • 相关阅读:
    注解之------@WebService
    注解之----@component,@controller,@service ,@repository简介
    Java 之 I/O
    标签之----@Override
    注解之----@Resource
    弹指之间 -- 简谱
    弹指之间 -- Prerequisites
    MVC5 + EF6 完整入门教程三
    MVC5 + EF6 入门完整教程二
    MVC5 + EF6 入门完整教程
  • 原文地址:https://www.cnblogs.com/zoumin123/p/9005132.html
Copyright © 2011-2022 走看看