.NET C#使用微信公眾號登錄網站

来源:http://www.cnblogs.com/yin2099/archive/2016/08/03/5732178.html
-Advertisement-
Play Games

適用於: 本文適用於有一定微信開發基礎的用戶 引言: 花了300大洋申請了微信公眾平臺後,發現不能使用微信公眾號登錄網站(非微信打開)獲得微信帳號。仔細研究後才發現還要再花300大洋申請微信開放平臺才能接入網站的登錄。於是做為屌絲程式員的我想到了自己做一個登錄介面。 工具和環境: 1. VS2013 ...


適用於:

本文適用於有一定微信開發基礎的用戶  

引言:

花了300大洋申請了微信公眾平臺後,發現不能使用微信公眾號登錄網站(非微信打開)獲得微信帳號。仔細研究後才發現還要再花300大洋申請微信開放平臺才能接入網站的登錄。於是做為屌絲程式員的我想到了自己做一個登錄介面。

工具和環境:

1. VS2013 .net4.0 C# MVC4.0 Razor

2.插件

  A. Microsoft.AspNet.SignalR;時時獲取後臺數據

  B.Gma.QrCodeNet.Encoding;文本生成二維碼

實現的目標

  1. 在電腦上打開網站登錄頁,提示用戶使用微信掃描登錄確認。

  2.用戶通過微信掃描確認後,電腦自動收到確認信息跳轉到網站主頁。

原理分析

   1.SignalR是一個神奇的工具,能從瀏覽器A發送信息到伺服器,伺服器自動推送消息到指定的瀏覽器B。那麼我的計劃是用電腦的瀏覽器打開登錄頁,生成一個二維碼(內容為帶有微信公眾平臺網頁用戶受權的網址),用微信的描碼功能打開這個網站。將獲取的微信用戶OPENID通過SignalR發送到電腦瀏覽器,實現登錄功能

實現過程

  1.微信公從平臺的註冊和許可權(略過...)

  2.VS2013中新建MVC網站,我用的環境為.NET4.0 C# MVC4.0  Razor引擎(個人習慣)。

 

3.安裝 SignalR

VS2013 點擊工具 ==> 庫程式包管理器 ==> 程式包管理控制台

輸入以下命令:

Install-Package Microsoft.AspNet.SignalR -Version 1.1.4

.net4.0 Mvc4環境下建議安裝1.1.4高版本安裝不上

 安裝 SingnalR成功

 

 設置SignalR

var config = new Microsoft.AspNet.SignalR.HubConfiguration();
config.EnableCrossDomain = true;
RouteTable.Routes.MapHubs(config);

新建一個類 PushHub.cs



using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WD.C.Utility
{
    /// <summary>
    /// 標註Single javascription要連接的名稱
    /// </summary>
    [HubName("pushHub")]
    public class PushHub : Hub
    {
        /// <summary>
        /// 臨時保存請求的用戶
        /// </summary>
        static Dictionary<string, string> rlist = new Dictionary<string, string>();
      
        /// <summary>
        /// 登錄請求的用戶;打開Login頁執行本方法,用於記錄瀏覽器連接的ID
        /// </summary>
        public void ruserConnected()
        {
            if (!rlist.ContainsKey(Context.ConnectionId))
                rlist.Add(Context.ConnectionId, string.Empty);

            //Client方式表示對指定ID的瀏覽器發送GetUserId方法,瀏覽器通過javascrip方法GetUserId(string)得到後臺發來的Context.ConnectionId
            Clients.Client(Context.ConnectionId).GetUserId(Context.ConnectionId);
        }
        /// <summary>
        /// 實際登錄的用戶
        /// </summary>
        /// <param name="ruser">請求的用戶ID</param>
        /// <param name="logUserID">微信OPENID</param>
        public void logUserConnected(string ruser, string logUserID)
        {
            if (rlist.ContainsKey(ruser))
            {
                rlist.Remove(ruser);

                //Client方式表示對指定ID的瀏覽器發送GetUserId方法,瀏覽器通過javascrip方法userLoginSuccessful(bool,string)得到後臺發來的登錄成功,和微信OPENID
                Clients.Client(ruser).userLoginSuccessful(true, logUserID);
            }
        }

        
    }
}

新建一個MVC控制器"LoginController.cs",這個不會看別的教程;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace WD.C.Controllers
{
    public class LoginController : Controller
    {
        //
        // GET: /Login/

        /// <summary>
        /// 登錄主頁,電腦端打開
        /// </summary>
        /// <returns></returns>
        public ActionResult Index()
        {
            /*參考 https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842&token=&lang=zh_CN
             *1.URL用於生成二維碼給微信掃描
             *2.格式參考微信公從平臺幫助
             * https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect 若提示“該鏈接無法訪問”,請檢查參數是否填寫錯誤,是否擁有scope參數對應的授權作用域許可權。 
             *3.REDIRECT_URI內容為返回地址,需要開發者需要先到公眾平臺官網中的“開發 - 介面許可權 - 網頁服務 - 網頁帳號 - 網頁授權獲取用戶基本信息”的配置選項中,修改授權回調功能變數名稱
             *4.REDIRECT_URI應回調到WxLog頁併進行URLEncode編碼,如: redirect_uri=GetURLEncode("http://你的網站/Login/WxLog?ruser=");  ruser為PushHub中的Context.ConnectionId到View中配置 
             *
             */
            ViewBag.Url = string.Format("https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type=code&scope=snsapi_base&state={2}#wechat_redirect", B.Helper.AppID, GetURLEncode("http://你的網站/Login/WxLog?ruser="), Guid.NewGuid());
            return View();
        }

        /// <summary>
        /// 登錄確認頁,微信端打開
        /// </summary>
        /// <param name="ruser"></param>
        /// <returns></returns>
        public ActionResult WxLog(string ruser)
        {

//使用微信登錄
if (!string.IsNullOrEmpty(code))
{
string loguser= B.Helper.GetOpenIDByCode(code);
Session["LogUserID"] =loguser;
ViewBag.LogUserID = loguser;
}

ViewBag.ruser = ruser;
return View();


        }



        

    }
}

控制器 "QRController.cs"用於文本生成二維碼

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace WD.C.Controllers
{
    public class QRController : Controller
    {
        //
        // GET: /QR/

        public ActionResult Index()
        {
            return View();
        }
        /// <summary>
        /// 獲得2維碼圖片
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public ActionResult GetQRCodeImg(string str)
        {
            using (var ms = new System.IO.MemoryStream())
            {

                string stringtest = str;
                GetQRCode(stringtest, ms);
                Response.ContentType = "image/Png";
                Response.OutputStream.Write(ms.GetBuffer(), 0, (int)ms.Length);
                System.Drawing.Bitmap img = new System.Drawing.Bitmap(100, 100);
                img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                Response.End();
                return File(ms.ToArray(), @"image/jpeg");
            }
        }
        private static bool GetQRCode(string strContent, System.IO.MemoryStream ms)
        {

            Gma.QrCodeNet.Encoding.ErrorCorrectionLevel Ecl = Gma.QrCodeNet.Encoding.ErrorCorrectionLevel.M; //誤差校正水平 
            string Content = strContent;//待編碼內容
            Gma.QrCodeNet.Encoding.Windows.Render.QuietZoneModules QuietZones = Gma.QrCodeNet.Encoding.Windows.Render.QuietZoneModules.Two;  //空白區域 
            int ModuleSize = 12;//大小
            var encoder = new Gma.QrCodeNet.Encoding.QrEncoder(Ecl);
            Gma.QrCodeNet.Encoding.QrCode qr;
            if (encoder.TryEncode(Content, out qr))//對內容進行編碼,並保存生成的矩陣
            {
                var render = new Gma.QrCodeNet.Encoding.Windows.Render.GraphicsRenderer(new Gma.QrCodeNet.Encoding.Windows.Render.FixedModuleSize(ModuleSize, QuietZones));
                render.WriteToStream(qr.Matrix, System.Drawing.Imaging.ImageFormat.Png, ms);
            }
            else
            {
                return false;
            }
            return true;
        }
    }
}

視圖 開啟SignalR

 var chat = $.connection.pushHub;
        $.connection.hub.start().done(function () {
             chat.server.ruserConnected(); 
        });
$.connection.pushHub對應

 chat.server.ruserConnected();對應


表示調用"pushHub"運行後執行 runserConnected方法,在臨時表中增加當前瀏覽器的ConnectionID
chat.client.getUserId = function (ruserid)
{

  //二維碼生成的文本
$("#loga").attr("src", "@ViewBag.Url" + ruserid);
}

 

表示台後數據 

收到數據後返回到游覽器

chat.client.userLoginSuccessful = function (r, userid) {
            if (r) {
                $.post("/Login/AddSession/", { userid: userid }, function (r2) {
                    if (r2) {
                        location.href = "/Home/";
                    }
                })
            }
        }; 

 

用戶通過微信登錄後

 

接收微信OpenID  

$.post("/Login/AddSession/", { userid: userid }, function (r2) {
if (r2) {
location.href = "/Home/";
}
})

執行 Post到後臺增加登錄信息,成功後轉到/Home/主頁

 /// <summary>
        /// 保存微信確認登錄後返回的OPENID,做為網站的Session["LogUserID"]
        /// </summary>
        /// <param name="userid"></param>
        /// <returns></returns>
        public JsonResult AddSession(string userid)
        {
            Session["LogUserID"] = userid;
            return Json(true);
        }

 

Login/WxLog.cshtml 本頁在微信上打開

@{
    ViewBag.Title = "WxLog";
}
<script src="~/Scripts/jquery.signalR-1.1.4.min.js"></script>
<script src="~/signalr/hubs"></script>
<script>
    $(function () {
        //連接SignalR pushHab
        var chat = $.connection.pushHub;
        //啟動
        $.connection.hub.start().done();

        $("#btnLog").click(function () {
            //登錄,發送信息到伺服器
            chat.server.logUserConnected("@ViewBag.ruser","@ViewBag.LogUserID");
        });
    });
</script>
<h2>WxLog</h2>

<a href="#" id="btnLog">登錄</a>
@{
    ViewBag.Title = "Index";
}
   @Scripts.Render("~/bundles/jquery")
<script src="~/Scripts/jquery.signalR-1.1.4.min.js"></script>
<script src="~/signalr/hubs"></script>

<script type='text/javascript'>
    $(function () {
        var chat = $.connection.pushHub;
        $.connection.hub.start().done(function () {
             chat.server.ruserConnected();
        });
        chat.client.getUserId = function (ruserid)
        {
            $("#loga").attr("src", "@ViewBag.Url" + ruserid);
        }
        chat.client.userLoginSuccessful = function (r, userid) {
            if (r) {
                        location.href = "/Home/";
                })
            }
        };
    });

</script>
<header>
    <a href="~/Home/" class="iconfont backIcon">&#60;</a>
    <h1>用戶登錄</h1>
</header>
<div style="height:1rem;"></div>
請使用微信登錄掃描以下二維碼生產圖片
<div>
    <img id="loga" src="#" width="90%" />
</div>

 

GetOpenIDByCode(code)方法

參考 https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842&token=&lang=zh_CN

對於已關註公眾號的用戶,如果用戶從公眾號的會話或者自定義菜單進入本公眾號的網頁授權頁,即使是scope為snsapi_userinfo,也是靜默授權,用戶無感知。 

具體而言,網頁授權流程分為四步:

1、引導用戶進入授權頁面同意授權,獲取code 

2、通過code換取網頁授權access_token(與基礎支持中的access_token不同) 

3、如果需要,開發者可以刷新網頁授權access_token,避免過期 

4、通過網頁授權access_token和openid獲取用戶基本信息(支持UnionID機制) 

 public static string GetOpenIDByCode(string code)
        {
            string url =string.Format( "https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code",AppID,AppSecret, code);
            using (System.Net.WebClient client = new System.Net.WebClient())
            {
               string tempstr= client.DownloadString( url);
              var regex= new Regex(@"\""openid\"":\""[^\""]+?\"",", RegexOptions.IgnoreCase);
            string tempstr2=  regex.Match(tempstr).Value;
            return tempstr2.Substring(10, tempstr2.Length - 12);
            }
        }

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 喜迎Win10周年版更新,湖南衛視旗下唯一官方視頻平臺《芒果TV》近日向Win10商店提交了芒果TV UWP V3.1.0版,這次不僅在上一版(V3.0.0)的基礎上完善了用戶呼聲最高的手機版視頻離線下載功能,而且為追劇達人帶來了跳過片頭片尾的貼心福利。 ...
  • 概述 XDT是Asp.net 4.0中的一個新特性,可以讓使用者在Web項目中在不同的生成類型下,快速切換配置文件(如在debug場景下使用測試配置資料庫,在Release場景下使用正式配置資料庫)。 但在非web項目中,VS並未提供如此方便的功能。這時如果我們同樣想使用xdt transforms ...
  • 今天編碼時遇到了一個問題,大致描述就是去讀取excel中的某列,如圖: 這些是文件名,類似一個對應關係表,然後代碼去查找對應的文件。 斷點調試出來的內容也是正常,但是都匹配不到(文件真實存在),在打出log時發現了端倪: 有些空格變成了問號。難道是我的打開方式不對麽。。。? 嘗試了幾種不同編碼打開, ...
  • 一、 通過AccountManagement 程式集(System.DirectoryServices.AccountManagement) acountManagement 包含有: 1. UserPrincipals 2. GroupPrincipal 3.ComputerPrincipals ...
  • 最近學習xamarin。剛好 手上有一個lumia 930.所以試一試把uwp app部署到手機上,並真機調試一把。 目前環境: 1.開發pc電腦是win10,版本1607.加入了insider,所以版本比較高。 2.手機是 lumia 930.版本 1511,手機未加入insider,所以是穩定版 ...
  • 放暑假了,生活基本穩定下來,項目的剩餘部分也要開始慢慢的研究了。 項目GitHub地址: https://github.com/Andyahui/xgyxsh_WeiXin SDK的GitHub地址:https://github.com/JeffreySu/WeiXinMPSDK/ SDK官方介紹博 ...
  • 一、前言 可能項目規模較小,項目中除了增刪改查就只剩下業務流程,以前都沒怎麼弄明白的東西時間長了就越發的模糊了... 二、使用場景 MSDN:delegate 是一種可用於封裝命名或匿名方法的引用類型。 委托類似於 C++ 中的函數指針;但是,委托是類型安全和可靠的。 BeginInvoke 方法啟 ...
  • 1. 使用場景 來著stackorverflow controls concurrent access to a shared resource. access to the resource will be requested from multiple, disparate parts of t ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...