.NetCore 接入微信JSSDK调用微信扫一扫
作者:互联网
前言:
说一下需求:微信网页通过扫描二维码,获取二维码数据,再进行后续业务操作
前期准备:
1:准备微信公众号(因为微信网页属于公众号范畴,所以需要申请公众号)
公众号申请地址:https://open.weixin.qq.com/cgi-bin/frame?t=home/mp_tmpl&lang=zh_CN
如果不使用扫一扫,使用其他接口的话可以不用申请公众号,使用测试号也可以,但是测试号可以使用的功能不全
测试号申请地址:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
2:准备域名
因为微信接口不能使用Ip去访问,所以需要准备一个域名,如果没有域名的同学可以选择使用花生壳,内网穿透
花生壳下载地址:https://hsk.oray.com/
3:配置公众号
1:设置JS接口安全域名
这里填我们准备好的域名就ok
2:公众号开发信息配置
注意:IP白名单必须与与JS接口安全域名对应的IP相同
4:代码,代码搬过去就能用,难的是配置
新建一个MVC项目
新建工具类WxHelper
public static class WxHelper
{
private static ILog log = LogManager.GetLogger(Startup.repository.Name, typeof(WxHelper));
//获取AccessToken
public static string Request_Url(string _appid, string _appsecret)
{
string _url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + _appid + "&secret=" + _appsecret;
string method = "GET";
HttpWebRequest request = WebRequest.Create(_url) as HttpWebRequest;
CookieContainer cookieContainer = new CookieContainer();
request.CookieContainer = cookieContainer;
request.AllowAutoRedirect = true;
request.Method = method;
request.ContentType = "text/html";
request.Headers.Add("charset", "utf-8");
//发送请求并获取相应回应数据
using HttpWebResponse response = request.GetResponse() as HttpWebResponse;
//直到request.GetResponse()程序才开始向目标网页发送Post请求
using Stream responseStream = response.GetResponseStream();
using StreamReader sr = new StreamReader(responseStream, Encoding.UTF8);
//返回结果网页(html)代码
string content = sr.ReadToEnd();
//由于微信服务器返回的JSON串中包含了很多信息,我们只需要将AccessToken获取就可以了,需要将JSON拆分
String[] str = content.Split('"');
content = str[3];
return content;
}
//根据AccessToken来获取jsapi_ticket
public static string Requestjsapi_ticket(string accesstoken)
{
string _accesstoken = accesstoken;
string url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + _accesstoken + "&type=jsapi";
string method = "GET";
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
CookieContainer cookieContainer = new CookieContainer();
request.CookieContainer = cookieContainer;
request.AllowAutoRedirect = true;
request.Method = method;
request.ContentType = "text/html";
request.Headers.Add("charset", "utf-8");
//发送请求并获取相应回应数据
using HttpWebResponse response = request.GetResponse() as HttpWebResponse;
//直到request.GetResponse()程序才开始向目标网页发送Post请求
using Stream responseStream = response.GetResponseStream();
using StreamReader sr = new StreamReader(responseStream, Encoding.UTF8);
//返回结果网页(html)代码
string content = sr.ReadToEnd();
//同样,返回的JSON中只要取出ticket的信息即可
String[] str = content.Split('"');
content = str[9];
return content;
}
public static string Requestjsapi_ticket2(string accesstoken)
{
var response = string.Empty;
var baseAddress = "https://api.weixin.qq.com";
string url = $"{baseAddress}/cgi-bin/ticket/getticket?access_token={accesstoken}&type=jsapi";
using var client = new HttpClient();
client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "text/html");
client.BaseAddress = new Uri(baseAddress);
response = client.GetStringAsync(url).Result;
String[] str = response.Split('"');
var content = str[9];
return content;
//var response = string.Empty;
//try
//{
// var baseAddress = "https://api.weixin.qq.com";
// string url = $"{baseAddress}/cgi-bin/ticket/getticket?access_token={accesstoken}&type=jsapi";
// using var client = new HttpClient();
// client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "text/html");
// client.BaseAddress = new Uri(baseAddress);
// response = client.GetStringAsync(url).Result;
// String[] str = response.Split('"');
// var content = str[9];
// return content;
//}
//catch (Exception ex)
//{
// log.Error($"{response};{ex}");
//}
//return response;
}
//接下来就是辅助工具类,生成随机字符串
#region 字符串随机 CreatenNonce_str()
private static string[] strs = new string[]
{
"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z",
"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"
};
public static string CreatenNonce_str()
{
Random r = new Random();
var sb = new StringBuilder();
var length = strs.Length;
for (int i = 0; i < 15; i++)
{
sb.Append(strs[r.Next(length - 1)]);
}
return sb.ToString();
}
#endregion
//生成时间戳,备用
#region 时间戳生成 CreatenTimestamp()
public static long CreatenTimestamp()
{
return (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
}
#endregion
//获取签名,这里的三个参数分别为前面生成的ticket,随机字符串以及时间戳
#region 获取签名 GetSignature()
public static string GetSignature(string jsapi_ticket, string noncestr, long timestamp, string url)
{
var string1Builder = new StringBuilder();
string1Builder.Append("jsapi_ticket=").Append(jsapi_ticket).Append("&")
.Append("noncestr=").Append(noncestr).Append("&")
.Append("timestamp=").Append(timestamp).Append("&")
.Append("url=").Append(url.IndexOf("#") >= 0 ? url.Substring(0, url.IndexOf("#")) : url);
return SHA1(string1Builder.ToString());
}
#endregion
//最后就是SHA1的加密算法工具
#region 加密签名算法 SHA1(content)
//加密签名算法
public static string SHA1(string content)
{
return SHA1(content, Encoding.UTF8);
}
//加密签名
public static string SHA1(string content, Encoding encode)
{
try
{
SHA1 sha1 = new SHA1CryptoServiceProvider();
byte[] bytes_in = encode.GetBytes(content);
byte[] bytes_out = sha1.ComputeHash(bytes_in);
sha1.Dispose();
string result = BitConverter.ToString(bytes_out);
result = result.Replace("-", "");
return result;
}
catch (Exception ex)
{
throw new Exception("SHA1加密出错:" + ex.Message);
}
}
#endregion
}
新建缓存Helper 缓存token
public class MemoryCacheHelper
{
public static readonly IMemoryCache _memoryCache = new MemoryCache(new MemoryCacheOptions());
/// <summary>
/// 是否存在此缓存
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static bool Exists(string key)
{
if (string.IsNullOrWhiteSpace(key))
throw new ArgumentNullException(nameof(key));
object v = null;
return _memoryCache.TryGetValue<object>(key, out v);
}
/// <summary>
/// 取得缓存数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <returns></returns>
public static T GetCache<T>(string key) where T : class
{
if (string.IsNullOrWhiteSpace(key))
throw new ArgumentNullException(nameof(key));
T v = null;
_memoryCache.TryGetValue<T>(key, out v);
return v;
}
/// <summary>
/// 设置缓存,绝对过期
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="expirationMinute">间隔分钟</param>
/// CommonManager.CacheObj.Save<RedisCacheHelper>("test", "RedisCache works!", 30);
public static void SetCache(string key, object value, double expirationMinute)
{
if (string.IsNullOrWhiteSpace(key))
throw new ArgumentNullException(nameof(key));
if (value == null)
throw new ArgumentNullException(nameof(value));
object v = null;
if (_memoryCache.TryGetValue(key, out v))
_memoryCache.Remove(key);
DateTime now = DateTime.Now;
TimeSpan ts = now.AddMinutes(expirationMinute) - DateTime.Now;
_memoryCache.Set<object>(key, value, ts);
}
/// <summary>
/// 释放
/// </summary>
public static void Dispose()
{
if (_memoryCache != null)
_memoryCache.Dispose();
//GC.SuppressFinalize(this);
}
}
html(此处只写了js 自行建立button调用)
//引入wxjssdk
<script src="http://res.wx.qq.com/open/js/jweixin-1.1.0.js"> </script>
<script>
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '@ViewBag.appid', // 必填,公众号的唯一标识
timestamp: '@ViewBag.timestamp', // 必填,生成签名的时间戳
nonceStr: '@ViewBag.noncestr', // 必填,生成签名的随机串
signature: '@ViewBag.sinature',// 必填,签名
jsApiList: ['checkJsApi',
//这里的接口在官方文档中都有涉及,我们只需要调用微信扫一扫即可
//'chooseImage',
//'previewImage',
// 'uploadImage',
// 'downloadImage',
// 'getNetworkType',//网络状态接口
// 'openLocation',//使用微信内置地图查看地理位置接口
// 'getLocation', //获取地理位置接口
// 'hideOptionMenu',//界面操作接口1
// 'showOptionMenu',//界面操作接口2
// 'closeWindow', 界面操作接口3
// 'hideMenuItems',界面操作接口4
// 'showMenuItems',界面操作接口5
// 'hideAllNonBaseMenuItem',界面操作接口6
// 'showAllNonBaseMenuItem',界面操作接口7
'scanQRCode'// 微信扫一扫接口
]
});
<!--开始扫描 在合适的地方调用此方法唤醒扫一扫-->
function scan(){
wx.ready(function () {
wx.scanQRCode({
needResult: 1,
desc: 'scanQRCode desc',
success: function (res) {}
});
})
}
</script>
controller调用
private readonly static object lockobj = new object();
public ActionResult Index()
{
//此处若是测试可以写死
//配置文件获取配置信息
var appid = configuration.GetValue<string>("appid");
var appsecret = configuration.GetValue<string>("appsecret");
//返回调用扫一扫需要的配置信息
//获取ACCESS_TOKEN
string _token = string.Empty;
string _finalticket= string.Empty;
if (!MemoryCacheHelper.Exists("_token"))
{
lock (lockobj)
{
if (!MemoryCacheHelper.Exists("_token"))
{
_token = WxHelper.Request_Url(appid, appsecret);
//缓存token
MemoryCacheHelper.SetCache("_token", _token, 115);
}
else
_token = MemoryCacheHelper.GetCache<string>("_token");
}
}
else
{
_token = MemoryCacheHelper.GetCache<string>("_token");
}
//获取Ticket
string _ticket = WxHelper.Requestjsapi_ticket2(_token);
//获取ticket
_finalticket = _ticket;
//获取noncestr
string _noncestr = WxHelper.CreatenNonce_str();
//获取timestamp
long _timestamp = WxHelper.CreatenTimestamp();
//获取sinature
string _url = HttpContext.Request.GetDisplayUrl();
string _sinature = WxHelper.GetSignature(_finalticket, _noncestr, _timestamp, _url).ToLower();
ViewBag.appid = configuration.GetValue<string>("appid");
ViewBag.timestamp = _timestamp;
ViewBag.noncestr = _noncestr;
ViewBag.sinature = _sinature;
return View();
}
标签:string,JSSDK,NetCore,url,微信,content,token,static,new 来源: https://www.cnblogs.com/xigua55/p/16455514.html