. Net c # use the public account to log on to the website,
Applicable:
This article applies to users with certain development Basics
Introduction:
After applying for the public platform for 300 oceans, I found that I could not use the public account to log on to the website (not open) to obtain an account. After careful research, we found that it would take another 300 oceans to apply for an open platform to access website login. As a programmer, I thought of myself as a login interface.
Tools and environment:
1. VS2013. net4.0 C # MVC4.0 Razor
2. Plug-ins
A. Microsoft. AspNet. SignalR; obtain background data from time to time
B. Gma. QrCodeNet. Encoding; generate a QR code
Goals
1. Open the website logon page on your computer and prompt you to use scan for Logon confirmation.
2. After the user passes the scan confirmation, the computer automatically receives the confirmation information to jump to the website homepage.
Principle Analysis
1. SignalR is A magic tool that sends messages from browser A to the server, and the server automatically pushes messages to the specified browser B. In this case, I plan to open the login page in a computer browser, generate a QR code (the content is a website with the authorization of the public platform Web page user), and use the code tracking function to open the website. Send the obtained user's OPENID to the Computer Browser through SignalR for logon.
Implementation Process
1. Registration and permissions of the Public slave platform (skipped ...)
2. Create an MVC website in VS2013. I use the. NET4.0 C # MVC4.0 Razor engine (my personal habits ).
3. Install SignalR
VS2013 click tool ==> Library Program Package Manager ==> package Management Console
Enter the following command:
Install-Package Microsoft. AspNet. SignalR-Version 1.1.4
In the. net4.0 Mvc4 environment, we recommend that you install version 1.1.4 or later.
SingnalR is successfully installed.
Set SignalR
Var config = new Microsoft. AspNet. SignalR. HubConfiguration ();
Config. EnableCrossDomain = true;
RouteTable. Routes. MapHubs (config );
Create a class PushHub. cs
Using Microsoft. aspNet. signalR; using Microsoft. aspNet. signalR. hubs; using System. collections. generic; using System. linq; using System. web; namespace WD. c. utility {// <summary> /// specify the name of the Single javascription to be connected /// </summary> [HubName ("pushHub")] public class PushHub: hub {// <summary> /// user who temporarily saves the request /// </summary> static Dictionary <string, string> rlist = new Dictionary <string, string> (); /// <Summary> /// Login request user; this method is executed on the Login page to record the browser connection ID /// </summary> public void ruserConnected () {if (! Rlist. containsKey (Context. connectionId) rlist. add (Context. connectionId, string. empty); // The Client method indicates that the GetUserId method is sent to the browser with the specified ID. the browser uses the javascrip method GetUserId (string) to obtain the Context sent from the background. connectionId Clients. client (Context. connectionId ). getUserId (Context. connectionId );} /// <summary> /// user actually logged on /// </summary> /// <param name = "ruser"> requested user id </param> // /<param name = "logUserID"> OPENID </param> public void logUserConnected (string ruser, string logUserID) {if (rlist. containsKey (ruser) {rlist. remove (ruser); // The Client method indicates that the GetUserId method is sent to the browser with the specified ID. the browser uses the javascrip method userLoginSuccessful (bool, string) to obtain the logon success from the background, and the OPENID Clients. client (ruser ). userLoginSuccessful (true, logUserID );}}}}
Create an MVC controller "LoginController. cs", which will not be used in other tutorials;
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> // log on to the homepage, on the computer, /// </summary> /// <returns> </returns> public ActionResult Index () {/* Reference https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842&token=&lang=zh_CN * 1. The URL is used to generate a QR code for scanning * 2. For the format, refer to the help of the Public slave platform * https://open.weixin.qq.com/connect/oauth2/authorize?appid= APPID & redirect_uri = REDIRECT_URI & response_type = code & scope = SCOPE & state = STATE # wechat_redirect, whether the permission of the scope parameter is granted. * 3. the REDIRECT_URI content is the return address. You need to go to the "development-interface permission-webpage service-webpage account-webpage authorization to obtain user basic information" configuration option on the official website of the public platform, modify the authorization callback domain name * 4. REDIRECT_URI should be called back to the WxLog page for URLEncode encoding, such as: redirect_uri = GetURLEncode ("http: // your website/Login/WxLog? Ruser = "); ruser is the Context. ConnectionId in PushHub. Configure **/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: // your website/Login/WxLog? Ruser = "), Guid. newGuid (); return View () ;}/// <summary> // logon confirmation page, enable the client /// </summary> /// <param name = "ruser"> </param> /// <returns> </returns> public ActionResult WxLog (string ruser) {
// Use Logon
If (! String. IsNullOrEmpty (code ))
{
String loguser = B. Helper. GetOpenIDByCode (code );
Session ["LogUserID"] = loguser;
ViewBag. LogUserID = loguser;
}
ViewBag. ruser = ruser;
Return View ();
} }}
Controller "QRController. cs" is used to generate two-dimensional codes in text
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> /// obtain a 2-dimensional image // </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; // Error Correction level string Content = strContent; // the Content to be encoded Gma. qrCodeNet. encoding. windows. render. quietZoneModules QuietZones = Gma. qrCodeNet. encoding. windows. render. quietZoneModules. two; // Empty Area int ModuleSize = 12; // size var encoder = new Gma. qrCodeNet. encoding. qrEncoder (Ecl); Gma. qrCodeNet. encoding. qrCode qr; if (encoder. tryEncode (Content, out qr) // encode the Content and save the Generated Matrix {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 ;}}}
View enable SignalR
var chat = $.connection.pushHub; $.connection.hub.start().done(function () { chat.server.ruserConnected(); });
$. Connection. pushHub
Chat. server. ruserConnected ();
Call "pushHub" and run the runserConnected method. Add the ConnectionID of the current browser to the temporary table.
Chat. client. getUserId = function (ruserid) {// text generated by the QR code $ ("# loga "). attr ("src", "@ ViewBag. url "+ ruserid );}
Post-Platform Data
After receiving the data, return to the browser
chat.client.userLoginSuccessful = function (r, userid) { if (r) { $.post("/Login/AddSession/", { userid: userid }, function (r2) { if (r2) { location.href = "/Home/"; } }) } };
After a user logs on
Receive OpenID
$. Post ("/Login/AddSession/", {userid: userid}, function (r2 ){
If (r2 ){
Location. href = "/Home /";
}
})
Execute Post to add logon information to the background, and go to/Home
/// <Summary> /// Save the OPENID returned after confirming logon, session ["LogUserID"] /// </summary> /// <param name = "userid"> </param> /// <returns> </returns> public JsonResult AddSession (string userid) {Session ["LogUserID"] = userid; return Json (true );}
Login/WxLog. cshtml this page opens
@ {ViewBag. Title = "WxLog" ;}< script src = "~ /Scripts/jquery. signalR-1.1.4.min.js "> </script> <script src = "~ /Signalr/hubs "> </script> <script> $ (function () {// connect SignalR pushHab var chat =$. connection. pushHub; // start $. connection. hub. start (). done (); $ ("# btnLog "). click (function () {// log on, and send the message to the server chat. server. logUserConnected ("@ ViewBag. ruser "," @ ViewBag. logUserID ") ;};}); </script>
@ {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>
GetOpenIDByCode (code) Method
Reference https://mp.weixin.qq.com/wiki? T = resource/res_main & id = mp1421140842 & token = & lang = zh_CN
For users who have followed the public account, if the user enters the webpage authorization page of this public account from the public account session or custom menu, even if the scope is snsapi_userinfo, it is silent authorization, the user is imperceptible.
Specifically, the webpage authorization process is divided into four steps:
1. Instruct the user to go to the authorization page to agree to the authorization and obtain the code
2. Exchange code for webpage authorization access_token (different from access_token in Basic Support)
3. If necessary, the developer can refresh the webpage to authorize access_token to avoid expiration.
4. obtain basic user information through webpage authorization access_token and openid (UnionID mechanism supported)
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); } }