1. 程式人生 > >.netMVC企業微信網頁授權+註冊全局過濾器

.netMVC企業微信網頁授權+註冊全局過濾器

glob for init cgi http 一個 使用 QQ ==

微信網頁授權

  達到效果:企業應用只能在微信中查看,在瀏覽器中打開企業頁面,顯示無權限!

原理,用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>
}

.netMVC企業微信網頁授權+註冊全局過濾器