踩坑之 java微信wifi 配网airkiss

1 篇文章 0 订阅
1 篇文章 0 订阅

最近在负责微信WiFi连接硬件设备的需求

只想说 坑 坑 坑

配网过程中一直重复报两个错 1、config:fail,Error: 系统错误,错误码:40048,invalid url domain

                                                2、config:fail,Error: 系统错误,错误码:63002,invalid signature

总之 不是报 url错误,就是报 签名无效

崩溃,经过各方大佬的指教,终于求证出来

微信配网总结:1、微信公众号配置

                          2、先获取AccessToken,通过AccessToken来请求票据jsApiTicket,最后的调用签名signature

第一步:把服务器IP地址配置到微信公众号的白名单中

第二步:接口权限中找到设备功能,确保设备功能接口已获得

第三步:配置JS接口安全域名,可以放置路径或者域名,确保txt文件可以访问到

第四步:编写Java代码

package com.weixin.wifi;

import net.sf.json.JSONObject;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

/**
 * @author sf
 * @version 1.0
 * @date 2019/12/4 11:23
 */
@RestController
@RequestMapping("wifi")
public class Airkiss {

    static String appId="XXX";//第三方用户唯一凭证  

    public static String getAccessToken() {
        String access_token = "";
        String grant_type = "client_credential";//获取access_token填写client_credential   
        String secret="XXXX";//第三方用户唯一凭证密钥,即appsecret
        //这个url链接地址和参数皆不能变  
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type="+grant_type+"&appid="+appId+"&secret="+secret;
        try {
            URL urlGet = new URL(url);
            HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();
            http.setRequestMethod("GET"); // 必须是get方式请求  
            http.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
            http.setDoOutput(true);
            http.setDoInput(true);
            System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒  
            System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒  
            http.connect();
            InputStream is = http.getInputStream();
            int size = is.available();
            byte[] jsonBytes = new byte[size];
            is.read(jsonBytes);
            String message = new String(jsonBytes, "UTF-8");
            JSONObject demoJson = JSONObject.fromObject(message);
            System.out.println("JSON字符串:"+demoJson);
            access_token = demoJson.getString("access_token");
            is.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return access_token;
    }
    public static String getTicket(String access_token) {
        String ticket = null;
        String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+ access_token +"&type=jsapi";//这个url链接和参数不能变  
        try {
            URL urlGet = new URL(url);
            HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();
            http.setRequestMethod("GET"); // 必须是get方式请求  
            http.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
            http.setDoOutput(true);
            http.setDoInput(true);
            System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒  
            System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒  
            http.connect();
            InputStream is = http.getInputStream();
            int size = is.available();
            byte[] jsonBytes = new byte[size];
            is.read(jsonBytes);
            String message = new String(jsonBytes, "UTF-8");
            JSONObject demoJson = JSONObject.fromObject(message);
            System.out.println("jsapi字符串:"+demoJson);
            ticket = demoJson.getString("ticket");
            is.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ticket;
    }
    public static String SHA1(String decript) {
        try {
            MessageDigest digest = java.security.MessageDigest.getInstance("SHA-1");
            digest.update(decript.getBytes());
            byte messageDigest[] = digest.digest();
            // Create Hex String  
            StringBuffer hexString = new StringBuffer();
            // 字节数组转换为 十六进制 数  
            for (int i = 0; i < messageDigest.length; i++) {
            String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
            if (shaHex.length() < 2) {
            hexString.append(0);
            }
            hexString.append(shaHex);
            }
            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }
//********************************************************************************************//    
    public static String getnoncestr() {
        String noncestr = UUID.randomUUID().toString().replace("-", "").substring(0, 16);//随机字符串  
        return noncestr;
    }

    public static String gettimestamp() {
        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);//时间戳  当前时间 
        return timestamp;
    }
//********************************************************************************************//
    public static String times[] = {"0","0"};
    public static int a = 0;
    public static int b = 0;
    public static int n = 0;
    static String accessToken = null;
    static String jsapi_ticket = null;
//********************************************************************************************//    
    @RequestMapping(value = "/getSign")
    public static String[] getSignatur() {

        a = Integer.parseInt(times[1]);
        b = Integer.parseInt(times[0]);

        System.out.println("获取access时间:"+times[0]);
        System.out.println("当前获取access:"+times[1]);

        if(n == 0){//初始化获取参数
            //1、获取AccessToken 
            accessToken = getAccessToken();
            //2、获取Ticket   
            jsapi_ticket = getTicket(accessToken);
            n = 1;
        }

        if(a - b > 7000){//定时获取参数
            //1、获取AccessToken  
            String accessT = getAccessToken();
            String jsapi_t = getTicket(accessT);
            accessToken = accessT;
            jsapi_ticket = jsapi_t;
            times[0] = times[1];
        }

        //3、时间戳和随机字符串  
        String noncestr = getnoncestr();
        String timestamp = gettimestamp();
        times[1] = timestamp;

        System.out.println("accessToken:"+accessToken+"\njsapi_ticket:"+jsapi_ticket+"\n时间戳:"+timestamp+
                "\n随机字符串:"+noncestr);

        String url = "http://XXXX"; //重点:需要获取签名的页面url具体地址,例如:www.XXXX.com/wifi.html

        //5、将参数排序并拼接字符串  
        String str = "jsapi_ticket="+jsapi_ticket+"&noncestr="+noncestr+"&timestamp="+timestamp+"&url="+url;
        //6、将字符串进行sha1加密  
        String signature = SHA1(str);
        System.out.println("参数:"+str+"\n签名:"+signature);
        String[] sendstr = new String[4];
        sendstr[0] = appId;
        sendstr[1] = timestamp;
        sendstr[2] = noncestr;
        sendstr[3] = signature;

        return sendstr;
    }
}

这里的URL我要着重说明一下,踩坑就踩在这里了

url就是步骤五的页面地址

url为访问的页面

第五步:前端页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title></title>
</head>

<body>
</body>
<script src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script src="./wifiJs/jquery-3.3.1.min.js"></script>
<script>
    var x = []
    $.ajax({
        url:"/wifi/getSign",
        type:"GET",
        dataType:"JSON",
        async:false,
        success:function(res){
            x = res
        }
    })
    console.log(location.href)
    wx.config({
        beta : true, // 开启内测接口调用,注入wx.invoke方法
        debug : false, // 开启调试模式
        appId : x[0], // 第三方app唯一标识
        timestamp : x[1], // 生成签名的时间戳
        nonceStr : x[2], // 生成签名的随机串
        signature :x[3],// 签名
        jsApiList : ['configWXDeviceWiFi'] // 需要使用的jsapi列表
    });
    var second = 5;
    wx.ready(function () {
        wx.checkJsApi({
            jsApiList: ['configWXDeviceWiFi'],
            success: function(res) {
                wx.invoke('configWXDeviceWiFi', {}, function(res){
                    err_msg = res.err_msg
                    if(err_msg == 'configWXDeviceWiFi:ok') {
        console.log('yes');
                        $('#tips').html("配置 wifi 成功,正在跳转...");
                        return;
                    } else {
                        console.log('no');
                        $('#tips').html("配置 wifi 失败,是否再次扫描");
                    }
                    console.log('configWXDeviceWiFi', res);
                });
            }
        });
    }); 
    wx.error(function(res){
        // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
        console.log(res)
    });
    function count(){
        second--;
        $('#second').html(second);
        if(second == 0){
            //跳转到首页
            //window.location.href='/consumer/main'
        }
    }
</script>
</html>

第六步:在微信公众号——自定义菜单,找到自己的小程序,配置页面地址,页面地址为点击后要跳转的页面

以上配置完成:

在微信开发者工具中测试:测试地址为网页url地址,最后返回结果是没有此SDK或暂不支持此SDK模拟,所以在手机上测试,显示成功,可以拿个硬件连接起来测试了!!!

以上是微信配网中的踩坑经验

切记:url值得是页面访问网址

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值