JS-SDK(微信扫一扫生成签名)_微信sdk生成签名-程序员宅基地

技术标签: 微信  javascript  开发语言  


确保有 调起微信扫一扫接口权限,测试号可能不行;

一、简介(JS-SDK使用权限签名算法)

1、jsapi_ticket

生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket 。

1、参考以下文档获取access_token(有效期7200秒,开发者必须在自己的服务全局缓存access_token):https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html

2、用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket):https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi

成功返回如下JSON:

{
    
  "errcode":0,
  "errmsg":"ok",
  "ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
  "expires_in":7200
}

获得jsapi_ticket之后,就可以生成JS-SDK权限验证的签名了。

2、签名算法

签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。

即signature=sha1(string1)。 示例:

noncestr=Wm3WZYTPz0wzccnW
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg
timestamp=1414587457
url=http://mp.weixin.qq.com?params=value

步骤1. 对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1:

jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW&timestamp=1414587457&url=http://mp.weixin.qq.com?params=value

步骤2. 对string1进行sha1签名,得到signature:

0f9de62fce790f9a083d5c99e95740ceb90c27ed

参考文档:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#62

二、js

1、导入相关JS

<script type="text/javascript" http://test.com/zepto_touch.js"></script> 
<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> 

2、页面触发扫码元素

<img src="../../../images/right.jpg" onclick="scanCode()" class="img"> 

3、相关JS代码(参数以自己的为标准,如下只是举例)

<script type="text/javascript"> 
 var _appId = "wxz88dbd30e5580e59"; 
 var _data = {
     
  appId : _appId, 
  url : location.href, 
  t : Math.random() 
 }; 
 var _getWechatSignUrl = 'http://test.com/getWxSign.do'; 
 
 // 获取微信签名 
 $.ajax({
     
  url : _getWechatSignUrl, 
  data : _data, 
  success : function(o) {
     
   console.log(o); 
   if (o.returnCode == "00") {
     
    wxConfig(o.detail[0].timestamp, o.detail[0].nonceStr, o.detail[0].signature); 
   } 
  } 
 }); 
 function wxConfig(_timestamp, _nonceStr, _signature) {
     
  //alert('获取数据:'+_timestamp+'\n'+_nonceStr+'\n'+_signature); 
  console.log('获取数据:' + _timestamp + '\n' + _nonceStr + '\n' + _signature); 
  wx.config({
     
   debug : true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 
   appId : _appId, // 必填,公众号的唯一标识 
   timestamp : _timestamp, // 必填,生成签名的时间戳 
   nonceStr : _nonceStr, // 必填,生成签名的随机串 
   signature : _signature,// 必填,签名,见附录1 
   jsApiList : [ 'onMenuShareTimeline', 'onMenuShareAppMessage', 
     'onMenuShareQQ', 'onMenuShareWeibo', 'scanQRCode' ] 
  // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 
  }); 
 } 
 function scanCode() {
     
  wx.scanQRCode({
     
   needResult : 1, 
   scanType : [ "qrCode", "barCode" ], 
   success : function(res) {
     
    console.log(res) 
    alert(JSON.stringify(res)); 
    var result = res.resultStr; 
   }, 
   fail : function(res) {
     
    console.log(res) 
    alert(JSON.stringify(res)); 
 
   } 
  }); 
 } 
</script> 

三、后端接口(根据所需选一中即可)

1、.jsp文件写法

<%
	public String sendGet(String url, String charset, int timeout)
  {
    
	String result = "";
	try
	{
    
	  URL u = new URL(url);
	  try
	  {
    
		URLConnection conn = u.openConnection();
		conn.connect();
		conn.setConnectTimeout(timeout);
		BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), charset));
		String line="";
		while ((line = in.readLine()) != null)
		{
    
		 
		  result = result + line;
		}
		in.close();
	  } catch (IOException e) {
    
		return result;
	  }
	}
	catch (Exception e)
	{
    
	  return result;
	}
   
	return result;
  }
%>
		String nonceStr = WXPayUtil.generateNonceStr(); 
		Long s = System.currentTimeMillis() / 1000;//获取时间戳除以千变字符串
		String timeStamp = String.valueOf(s);

		json=new JsonUtil();
		json.addJsons();

		//获取acess_token
		String url ="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appId+"&secret="+secret+"";
		String backData=sendGet(url, "utf-8", 10000);
		String accessToken = (String) JSONObject.fromObject(backData).get("access_token");

		//获取jsapiTicket
		String urlStr = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+accessToken+"&type=jsapi";  
		String backData2=sendGet(urlStr, "utf-8", 10000);  
		String ticket = (String) JSONObject.fromObject(backData2).get("ticket");

		System.out.println("ticket:"+ticket);
		System.out.println("noncestr:"+nonceStr);
		String url2="http://ww.com/index.html";//填写自己所需的地址即可
		try {
    
			String shaStr = "jsapi_ticket=" + ticket + "&noncestr=" + nonceStr + "&timestamp=" + timeStamp + "&url=" + url2; 
			MessageDigest mDigest = MessageDigest.getInstance("SHA1"); 
			byte[] result = mDigest.digest(shaStr.getBytes()); 
			StringBuffer signature = new StringBuffer(); 
			for (int i = 0; i < result.length; i++) {
     
				signature.append(Integer.toString((result[i] & 0xff) + 0x100, 16).substring(1)); 
			}

			json.addJsonData("nonceStr",nonceStr);
			json.addJsonData("timestamp",timeStamp);
			json.addJsonData("signature",signature.toString());
		}catch (Exception e) {
    
			e.printStackTrace();
			json.addJsonData("success","1");
		}

2、.java文件写法

public String sendGet(String url, String charset, int timeout)
    {
    
        String result = "";
        try
        {
    
            URL u = new URL(url);
            try
            {
    
                URLConnection conn = u.openConnection();
                conn.connect();
                conn.setConnectTimeout(timeout);
                BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), charset));
                String line="";
                while ((line = in.readLine()) != null)
                {
    

                    result = result + line;
                }
                in.close();
            } catch (IOException e) {
    
                return result;
            }
        }
        catch (Exception e)
        {
    
            return result;
        }
        return result;
    }
    public Map jssdk(String url, String charset, int timeout){
    
        Map<String, String> map=new HashMap<String, String>();
        String nonceStr = WXPayUtil.generateNonceStr();//随机生产16位字符串,例如:Wm3WZYTPz0wzccnW
        Long s = System.currentTimeMillis() / 1000;//获取时间戳除以千变字符串
        String timeStamp = String.valueOf(s);

        //获取acess_token
        String url3 ="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appId+"&secret="+secret+"";
        String backData=sendGet(url3, "utf-8", 10000);
        String accessToken = (String) JSONObject.fromObject(backData).get("access_token");

        //获取jsapiTicket
        String urlStr = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+accessToken+"&type=jsapi";
        String backData2=sendGet(urlStr, "utf-8", 10000);
        String ticket = (String) JSONObject.fromObject(backData2).get("ticket");

        String url2="http://www.com/index.html";
        try {
    
            String shaStr = "jsapi_ticket=" + ticket + "&noncestr=" + nonceStr + "&timestamp=" + timeStamp + "&url=" + url2;
            MessageDigest mDigest = MessageDigest.getInstance("SHA1");
            byte[] result = mDigest.digest(shaStr.getBytes());
            StringBuffer signature = new StringBuffer();
            for (int i = 0; i < result.length; i++) {
    
                signature.append(Integer.toString((result[i] & 0xff) + 0x100, 16).substring(1));
            }

            map.put("nonceStr",nonceStr);
            map.put("timestamp",timeStamp);
            map.put("signature",signature.toString());
        }catch (Exception e) {
    
            e.printStackTrace();

        }
        return map;
    }

3、注意事项

①、url2为当前网页的URL,不包含#及其后面部分
如下图所示:
在这里插入图片描述
②签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。
③签名用的url必须是调用JS接口页面的完整URL。
④出于安全考虑,开发者必须在服务器端实现签名的逻辑。
如出现invalid signature 等错误详见微信开发文档附录5常见错误及解决办法。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_67677668/article/details/132342448

智能推荐

海康威视网络摄像头开发流程(五)------- 直播页面测试_ezuikit 测试的url-程序员宅基地

文章浏览阅读3.8k次。1、将下载好的萤石js插件,添加到SoringBoot项目中。位置可参考下图所示。(容易出错的地方,在将js插件在html页面引入时,发生路径错误的问题)所以如果对页面中引入js的路径不清楚,可参考下图所示存放路径。2、将ezuikit.js引入到demo-live.html中。(可直接将如下代码复制到你创建的html页面中)<!DOCTYPE html><html lan..._ezuikit 测试的url

如何确定组态王与多动能RTU的通信方式_组态王ua-程序员宅基地

文章浏览阅读322次。第二步,在弹出的对话框选择,设备驱动—>PLC—>莫迪康—>ModbusRTU—>COM,根据配置软件选择的协议选期期,这里以此为例,然后点击“下一步”。第四步,把使用虚拟串口打勾(GPRS设备),根据需要选择要生成虚拟口,这里以选择KVCOM1为例,然后点击“下一步”设备ID即Modbus地址(1-255) 使用DTU时,为下485接口上的设备地址。第六步,Modbus的从机地址,与配置软件相同,这里以1为例,点击“下一步“第五步,Modbus的从机地址,与配置软件相同,这里以1为例,点击“下一步“_组态王ua

npm超详细安装(包括配置环境变量)!!!npm安装教程(node.js安装教程)_npm安装配置-程序员宅基地

文章浏览阅读9.4k次,点赞22次,收藏19次。安装npm相当于安装node.js,Node.js已自带npm,安装Node.js时会一起安装,npm的作用就是对Node.js依赖的包进行管理,也可以理解为用来安装/卸载Node.js需要装的东西_npm安装配置

火车头采集器AI伪原创【php源码】-程序员宅基地

文章浏览阅读748次,点赞21次,收藏26次。大家好,小编来为大家解答以下问题,python基础训练100题,python入门100例题,现在让我们一起来看看吧!宝子们还在新手村练级的时候,不单要吸入基础知识,夯实自己的理论基础,还要去实际操作练练手啊!由于文章篇幅限制,不可能将100道题全部呈现在此除了这些,下面还有我整理好的基础入门学习资料,视频和讲解文案都很齐全,用来入门绝对靠谱,需要的自提。保证100%免费这不,贴心的我爆肝给大家整理了这份今天给大家分享100道Python练习题。大家一定要给我三连啊~

Linux Ubuntu 安装 Sublime Text (无法使用 wget 命令,使用安装包下载)_ubuntu 安装sumlime text打不开-程序员宅基地

文章浏览阅读1k次。 为了在 Linux ( Ubuntu) 上安装sublime,一般大家都会选择常见的教程或是 sublime 官网教程,然而在国内这种方法可能失效。为此,需要用安装包安装。以下就是使用官网安装包安装的教程。打开 sublime 官网后,点击右上角 download, 或是直接访问点击打开链接,即可看到各个平台上的安装包。选择 Linux 64 位版并下载。下载后,打开终端,进入安装..._ubuntu 安装sumlime text打不开

CrossOver for Mac 2024无需安装 Windows 即可以在 Mac 上运行游戏 Mac运行exe程序和游戏 CrossOver虚拟机 crossover运行免安装游戏包-程序员宅基地

文章浏览阅读563次,点赞13次,收藏6次。CrossOver24是一款类虚拟机软件,专为macOS和Linux用户设计。它的核心技术是Wine,这是一种在Linux和macOS等非Windows操作系统上运行Windows应用程序的开源软件。通过CrossOver24,用户可以在不购买Windows授权或使用传统虚拟机的情况下,直接在Mac或Linux系统上运行Windows软件和游戏。该软件还提供了丰富的功能,如自动配置、无缝集成和实时传输等,以实现高效的跨平台操作体验。

随便推点

一个用聊天的方式让ChatGPT写的线程安全的环形List_为什么gpt一写list就卡-程序员宅基地

文章浏览阅读1.7k次。一个用聊天的方式让ChatGPT帮我写的线程安全的环形List_为什么gpt一写list就卡

Tomcat自带的设置编码Filter-程序员宅基地

文章浏览阅读336次。我们在前面的文章里曾写过Web应用中乱码产生的原因和处理方式,旧文回顾:深度揭秘乱码问题背后的原因及解决方式其中我们提到可以通过Filter的方式来设置请求和响应的encoding,来解..._filterconfig selectencoding

javascript中encodeURI和decodeURI方法使用介绍_js encodeur decodeurl-程序员宅基地

文章浏览阅读651次。转自:http://www.jb51.net/article/36480.htmencodeURI和decodeURI是成对来使用的,因为浏览器的地址栏有中文字符的话,可以会出现不可预期的错误,所以可以encodeURI把非英文字符转化为英文编码,decodeURI可以用来把字符还原回来_js encodeur decodeurl

Android开发——打包apk遇到The destination folder does not exist or is not writeable-程序员宅基地

文章浏览阅读1.9w次,点赞6次,收藏3次。前言在日常的Android开发当中,我们肯定要打包apk。但是今天我打包的时候遇到一个很奇怪的问题Android The destination folder does not exist or is not writeable,大意是目标文件夹不存在或不可写。出现问题的原因以及解决办法上面有说报错的中文大意是:目标文件夹不存在或不可写。其实问题就在我们的打包界面当中图中标红的Desti..._the destination folder does not exist or is not writeable

Eclipse配置高大上环境-程序员宅基地

文章浏览阅读94次。一、配置代码编辑区的样式 <1>打开Eclipse,Help —> Install NewSoftware,界面如下: <2>点击add...,按下图所示操作: name:随意填写,Location:http://eclipse-color-th..._ecplise高大上设置

Linux安装MySQL-5.6.24-1.linux_glibc2.5.x86_64.rpm-bundle.tar_linux mysql 安装 mysql-5.6.24-1.linux_glibc2.5.x86_6-程序员宅基地

文章浏览阅读2.8k次。一,下载mysql:http://dev.mysql.com/downloads/mysql/; 打开页面之后,在Select Platform:下选择linux Generic,如果没有出现Linux的选项,请换一个浏览器试试。我用的谷歌版本不可以,换一个别的浏览器就行了,如果还是不行,需要换一个翻墙的浏览器。 二,下载完后解压缩并放到安装文件夹下: 1、MySQL-client-5.6.2_linux mysql 安装 mysql-5.6.24-1.linux_glibc2.5.x86_64.rpm-bundle