微信扫描二维码关注公众号登录网站

页面:


@{
Layout = "~/Views/Shared/_Layout.cshtml";
}


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ko" lang="ko">
<head>
<title>生成二维码</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no" />
<script src="/Scripts/jquery.min.js"></script>
<style>
.WxLoginPage {
width: 304px;
height: 412px;
}

.modal-header {
padding: 15px;
border-bottom: 1px solid #e5e5e5;
}

.modal-body {
position: relative;
padding: 15px;
}

.form-group {
margin-bottom: 15px;
}

.img-thumbnail {
display: inline-block;
max-width: 100%;
height: auto;
padding: 3px;
line-height: 1.42857143;
background-color: #fff;
border: 1px solid #ddd;
border-radius: 4px;
transition: all .2s ease-in-out;
}

.wx_close {
float: right;
font-size: 21px;
font-weight: 700;
line-height: 1;
color: #000;
text-shadow: 0 1px 0 #fff;
opacity: .2;
cursor: pointer;
border: 0;
background-color: white;
}

h4 {
font-size: 18px;
}

hr {
border: 0.7px solid #e5e5e5;
font-size: 0;
width: 265px;
}
</style>
</head>
<body>
<a href="javascript:WxGzhLogin();" style="margin-top:500px;">微信登录</a>
<div class="WxLoginPage" style="display:none;">
<div class="modal-header">
<button type="button" class="wx_close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">请使用微信扫码登录</h4>
</div>
<div class="modal-body">
<div class="form-group ">
<img id="qrcode" src="" class="img-thumbnail" alt="正在加载请稍后..." />
</div>
</div>
<hr />
</div>

<script type="text/javascript">

$(function () {
$("#btn").on("click", function () {
$.ajax({
url: "/Home/GetAccessToken",
dataType: "json",
type: "post",
success: function (data) {
$("#qrcode").attr("src", data);

//是否扫码关注公众号监听事件
GeLoginQrcode(data.Message);

}
});
});

//关闭
$(".wx_close").click(function () {
//关闭弹窗
layer.closeAll();
});

});
//微信扫码关注公众号登录弹窗
function WxGzhLogin() {
layer.open({
type: 1,
shade: 0.8,
title: false, //不显示标题
closeBtn: 0,
area: [‘304px‘, ‘412px‘],
content: $(‘.WxLoginPage‘) //捕获的元素,注意:最好该指定的元素要存放在body最外层,否则可能被其它的相对元素所影响
});
}

//是否扫码关注公众号监听事件,ajax长轮询
function GeLoginQrcode(Tiket) {
$.ajax({
url: "/Home/WxGzhLogin",
//dataType: "json",
timeout:15000,
data: { "Tiket": Tiket },
type: "post",
success: function (data) {
if (!data.Success) {
//等待1秒后执行监听事件
setTimeout(function () {
GeLoginQrcode(Tiket);
}, 1000);
} else {
window.location.href = data.Message;
}
},
complete: function (XMLHttpRequest, textStatus) {
//请求完成
if (XMLHttpRequest.readyState == "4") {
// alert(XMLHttpRequest.responseText);
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
if (textStatus == "timeout") {
timeout1 = timeout1 + 1;
if (timeout1 <= 10) {
GeLoginQrcode(Tiket);
}
}
}
});
}
</script>

</body>
</html>

 

控制器:

//得到测试的appid和AppSecret:http://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index

string AppID = "xxxx";
string AppSecret = "xxxx";

ResultBase result = new ResultBase();

public ActionResult WxGzh()
{
return View();
}

#region 得到二维码

public ActionResult CreateQrcode()
{
var AccessToken = GetAccessToken();
var qrcode = GetQrcode(AccessToken);
result.Data = qrcode;
result.Message = qrcode.Substring(qrcode.IndexOf(‘=‘) + 1);
return result;
}

//第一步:获取accesstoken,使用AppId和AppSecret:获取access_token
public string GetAccessToken()
{
string Url = "https://api.weixin.qq.com/cgi-bin/token";
string strUrl = Url + $"?grant_type=client_credential&appid={AppID}&secret={AppSecret}";
var request = (HttpWebRequest)WebRequest.Create(strUrl);
var response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
var info = JsonConvert.DeserializeObject<WxToken>(responseString);

return info.access_token;
}

//第二步:生成带参数的二维码,http请求方式: POST,参数access_token是第三步获取的access_token
public string GetQrcode(string access_token)
{
string url = "https://api.weixin.qq.com/cgi-bin/qrcode/create";
var strUrl = url + $"?access_token={access_token}";
var dic = new Dictionary<string, object>();
dic.Add("expire_seconds", "604800");
dic.Add("action_name", "QR_SCENE");

var dic2 = new Dictionary<string, string>();
dic2.Add("scene_id", "123");
var dic3 = new Dictionary<string, object>();
dic3.Add("scene", dic2);
dic.Add("action_info", dic3);

var result = HttpService.Post(strUrl, dic.ToJson(), false, 30);
var info = JsonConvert.DeserializeObject<Qrcode>(result);

return GetTicket(info.ticket);
}

//第三步:通过ticket得到图片二维码
public string GetTicket(string ticket)
{
string url = "https://mp.weixin.qq.com/cgi-bin/showqrcode";
var strUrl = url + $"?ticket={HttpUtility.UrlEncode(ticket)}";
return strUrl;
}

#endregion

#region 接口配置信息测试

/// <summary>
/// 在公众平台测试号测试代码才需要以下步骤,正式项目不需要域名映射,直接发布就可以
/// 第一步:
/// 测试接口http://s2691815y6.zicp.vip/Home/InterfaceTest(映射后的地址)
/// ★★★项目不需要发布,直接部署到IIS上,IIS上网站路径对应的是项目文件夹里面的项目文件名(就是和.sln解决方案同级的项目文件夹)
/// IP:* ,主机名:s3691815y6.zicp.vip(映射后的域名),端口:80
/// 第二步:
/// 进入公众平台测试号管理:http://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index
/// 第三步:(必须先发布再配置)
/// 接口配置信息修改:URL:http://s3691815y6.zicp.vip/Home/InterfaceTest Token:nmslwsnd(随便写,但是要和InterfaceTest方法里的Token一致)
/// 第四步:
/// 如果要调试就打断点:项目--》调试--》附加到进程--》显示所有用户的进程打勾--》找到w3wp.exe进程附加
/// </summary>
public void InterfaceTest()
{
if (Request.RequestType == "GET")
{
#region 验证请求来源是否是微信
string signature = Request["signature"].ToString();
string timestamp = Request["timestamp"].ToString();
string nonce = Request["nonce"].ToString();
string echostr = Request["echostr"].ToString();
string token = "nmslwsnd";//公众平台测试号管理--》接口配置信息修改的token,必须先把项目部署到IIS上再提交
List<string> list = new List<string>() { token, timestamp, nonce };
list.Sort();
string data = string.Join("", list);
byte[] temp1 = Encoding.UTF8.GetBytes(data);
SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider();
byte[] temp2 = sha.ComputeHash(temp1);

var hashCode = BitConverter.ToString(temp2);
hashCode = hashCode.Replace("-", "").ToLower();

if (hashCode == signature)
{
Response.Write(echostr);
Response.End();
}
#endregion
}
else
{
ProcessRequest(Request);
}
}
/// <summary>
/// 接收消息
/// </summary>
/// <param name="requset"></param>
public void ProcessRequest(HttpRequestBase requset)
{
string postString = string.Empty;
if (requset.HttpMethod.ToUpper() == "POST")
{
using (Stream stream = requset.InputStream)
{
byte[] postBytes = new byte[stream.Length];
stream.Read(postBytes, 0, (int)stream.Length);
postString = Encoding.UTF8.GetString(postBytes);
Handle(postString);
}
}
}
/// <summary>
/// 处理消息并应答
/// </summary>
/// <param name="postStr"></param>
public void Handle(string postStr)
{
MessageHelper messageHelper = new MessageHelper();
string responseString = messageHelper.ReturnMessage(postStr);
Response.ContentEncoding = Encoding.UTF8;
Response.Write(responseString);
}

#endregion

//是否扫码关注公众号监听事件
[HttpPost]
public ActionResult WxGzhLogin(string Tiket)
{
//用二维码的ticke值获取openid,取缓存的值,Tiket的值为key,取缓存的值


string wxopendid = "";
if (wxopendid != null)
{
var access_token = GetAccessToken();
string url = "https://api.weixin.qq.com/cgi-bin/user/info";
var strUrl = url + $"?access_token={access_token}&openid={wxopendid}&lang=zh_CN";
var request = (HttpWebRequest)WebRequest.Create(strUrl);
var response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
var info = responseString.FormJson<UserInfo>();
if (info != null)
{
//根据openid 判断vipinfo是否存在
//VipInfo vip = new VipInfo();
//vip.WeiXinOpenId = wxopendid;
//var isExitvip = vipbll.isExitVipInfo(vip);
//if (isExitvip == null)
//{

// result.Success = true;
// result.Message = "/home/phonebind?OpenId=" + wxopendid + "&Photo=" + info.headimgurl;//为空就跳到手机绑定页面
// return result;
//}
//else
//{
// //登录用户存入缓存,自己写存入缓存的代码


//}
}
result.Success = true;
result.Message = "";//回调地址,登录成功地址
return result;
}
else
{
result.Success = false;
result.Message = "用户未关注公众号";
return result;
}
}

[Serializable]
public class ResultBase : ActionResult
{

public ResultBase()
{
Success = true;
Code = "00";
Message = "成功";
}
/// <summary>
/// 是否成功
/// </summary>
public bool Success { get; set; }

/// <summary>
/// 消息代码
/// </summary>
public string Code { get; set; }

/// <summary>
/// 消息
/// </summary>
public string Message { get; set; }

/// <summary>
/// 数据
/// </summary>
public object Data { get; set; }

public override void ExecuteResult(ControllerContext context)
{
context.HttpContext.Response.ContentType = "application/json";
context.HttpContext.Response.Write(this.ToJson());
}

}

public class WxToken
{
public string access_token { get; set; }
public int expires_in { get; set; }
}

public class UserInfo
{
public int subscribe { get; set; }
// 关注状态(1是关注,0是未关注),未关注时获取不到其余信息
public string openid { get; set; }
public string nickname { get; set; }
public int sex { get; set; }
public string city { get; set; }
public string country { get; set; }
public string province { get; set; }
public string language { get; set; }
public string headimgurl { get; set; }
public string subscribe_time { get; set; }
public string unionid { get; set; }
public string remark { get; set; }
public string groupid { get; set; }
public string tagid_list { get; set; }
public string subscribe_scene { get; set; }
public string qr_scene { get; set; }
public string qr_scene_str { get; set; }
}

public class Qrcode
{
public string ticket { get; set; }
public int expire_seconds { get; set; }
public string url { get; set; }
}

 

/// <summary>
/// 回复类型
/// </summary>
public class ReplyType
{
/// <summary>
/// 普通文本消息
/// </summary>
public static string Message_Text
{
get
{
return @"<xml>
<ToUserName><![CDATA[{0}]]></ToUserName>
<FromUserName><![CDATA[{1}]]></FromUserName>
<CreateTime>{2}</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[{3}]]></Content>
</xml>";
}
}

}

/// <summary>
/// 接受/发送消息帮助类
/// </summary>
public class MessageHelper
{
/// <summary>
/// 返回消息
/// </summary>
/// <returns></returns>
public string ReturnMessage(string postStr)
{
string responseContent = string.Empty;
XmlDocument document = new XmlDocument();
document.Load(new MemoryStream(Encoding.GetEncoding("UTF-8").GetBytes(postStr)));
XmlNode MsgType = document.SelectSingleNode("/xml/MsgType");
if (MsgType != null)
{
switch (MsgType.InnerText)
{
case "event":
responseContent = EventHandle(document);//事件处理
break;
default:
break;
}
}
return responseContent;
}
/// <summary>
/// 处理事件
/// </summary>
/// <param name="xmldoc"></param>
/// <returns></returns>
private string EventHandle(XmlDocument xmldoc)
{
string responseContent = "";
XmlNode Event = xmldoc.SelectSingleNode("/xml/Event");
XmlNode EventKey = xmldoc.SelectSingleNode("/xml/EventKey");
XmlNode ToUserName = xmldoc.SelectSingleNode("/xml/ToUserName");
XmlNode FromUserName = xmldoc.SelectSingleNode("/xml/FromUserName");
XmlNode Ticket = xmldoc.SelectSingleNode("/xml/Ticket");
if (Event != null)
{
if (Event.InnerText.Equals("subscribe"))//用户点击关注时的事件推送
{
//把openid存入缓存,必须存入缓存,自己写,Ticket.InnerText的值为key,把FromUserName.InnerText的值存在Ticket.InnerText里


//weixin://,和http://有一样的格式,表达的意思类似,就是告知浏览器,采取什么协议解析URL内容,只是这里的weixin://只能是微信浏览器才能识别。
responseContent = string.Format(ReplyType.Message_Text, FromUserName.InnerText, ToUserName.InnerText, DateTime.Now.Ticks, "欢迎您关注我的公众号");
}
else if (Event.InnerText.Equals("unsubscribe"))//未关注
{
//do something..
}
else if (Event.InnerText.Equals("SCAN"))//用户已关注时的事件推送
{
//把openid存入缓存,必须存入缓存

}
}
return responseContent;
}

}

 

有些类自己封装一下

微信扫描二维码关注公众号登录网站

上一篇:使用 async await 封装微信小程序HTTP请求


下一篇:小程序支持原生async方法