微信扫一扫_微信扫一扫登录 - CSDN
  • 参考微信JS-SDK说明文档 尽管作用不是很大1.首先在JSP页面引入http://res.wx.qq.com/open/js/jweixin-1.1.0.js2.通过config接口注入权限验证配置

    参考微信JS-SDK说明文档 看到网上很多都说微信的说明文档很坑,在我看来,仔细阅读的话,介绍还是很全的。

    1.首先在JSP页面引入http://res.wx.qq.com/open/js/jweixin-1.1.0.js

    2.通过config接口注入权限验证配置

    wx.config({
        debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
        appId: '', // 必填,企业号的唯一标识,此处填写企业号corpid
        timestamp: , // 必填,生成签名的时间戳
        nonceStr: '', // 必填,生成签名的随机串
        signature: '',// 必填,签名,见附录1
        jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
    });

    3.通过ready接口处理成功验证

    wx.ready(function(){
        // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
    });

    4.通过error接口处理失败验证

    wx.error(function(res){
        // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
    });

    5.调起微信扫一扫

    wx.scanQRCode({
        desc: 'scanQRCode desc',
        needResult: 0, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
        scanType: ["qrCode","barCode"], // 可以指定扫二维码还是一维码,默认二者都有
        success: function (res) {
           // 回调
        }
        error: function(res){
              if(res.errMsg.indexOf('function_not_exist') > 0){
                   alert('版本过低请升级')
                }
         }
    });

    具体代码实现如下:

    scanBarcode.jsp

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html lang="zh-CN">
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=320.1,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
    <head>
        <link rel="stylesheet" href="http://203.195.235.76/jssdk/css/style.css"/>
        <script src="http://res.wx.qq.com/open/js/jweixin-1.1.0.js"></script>
        <script src="http://libs.baidu.com/jquery/2.0.0/jquery.js"></script>
        <link rel="stylesheet" href="../../../resources/css/example.css"/>
        <link rel="stylesheet" href="../../../resources/css/weui.min.css"/>
        <link rel="stylesheet" href="../../../resources/css/borrowScan.css"/>
    </head>
    <body>
    <div class="container" style="text-align: center;">
        <div class="body_bd body_fd">
            <a class="weui-btn weui-btn-primary weui-btn-zdy" id="scanQRCode1">
                <p>扫描条码</p>
            </a>
        </div>
    </div>
    <script type="text/javascript">
        $.ajax({
            url: "${pageContext.request.contextPath}/wechat/jsapisign",
            type: "post",
            data: {
                url: location.href.split('#')[0]
            },
            contentType: 'application/x-www-form-urlencoded;charset=utf-8',
            async: true,
            success: function (data) {
                wx.config({
                    debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                    appId: data.appid, // 必填,公众号的唯一标识
                    timestamp: data.timestamp, // 必填,生成签名的时间戳
                    nonceStr: data.nonceStr, // 必填,生成签名的随机串
                    signature: data.signature,// 必填,签名,见附录1
                    jsApiList: ["scanQRCode"] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
                });
            }
        });
    
        wx.ready(function () {
            // 9.1.2 扫描二维码并返回结果
            document.querySelector('#scanQRCode1').onclick = function () {
                wx.scanQRCode({
                    needResult: 1,
                    desc: 'scanQRCode desc',
                    success: function (res) {
                        //扫码后获取结果参数赋值给Input
                        var url = res.resultStr;
                        //商品条形码,取","后面的
                        if (url.indexOf(",") >= 0) {
                            var tempArray = url.split(',');
                            var barCode = tempArray[1];
                            window.location.href = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${basePath}/wechat/toBookDetail?barCode=" + barCode + "&response_type=code&scope=snsapi_base&state=BINDFACE#wechat_redirect";
                        } else {
                            alert("请对准条形码扫码!");
                        }
                    }
                });
            };
        });
    
        //初始化jsapi接口 状态
        wx.error(function (res) {
            alert("调用微信jsapi返回的状态:" + res.errMsg);
        });
    </script>
    </body>
    </html>

    微信验签代码 WxController.java

      /**
         * 微信验签
         * @param url
         * @return
         */
        @RequestMapping(value = "/jsapisign", method = {RequestMethod.GET, RequestMethod.POST}, produces = MEDIATYPE_CHARSET_JSON_UTF8)
        @ResponseBody
        public String jsApiSign(String url) {
            //添加微信js签名信息
            Map<String, String> signMap = WXJsapiticket.jsApiSign(url);
            return JSON.toJSONString(signMap);
        }

    用到的方法类

    WXJsapiticket.java

    public class WXJsapiticket {
        private static Logger logger = LoggerFactory.getLogger(WxController.class);
        /**
         * 微信jsapi验签
         * @param url
         * @return
         */
        public static Map<String, String> jsApiSign(String url) {
            Map<String, String> ret = new HashMap<String, String>();
            String nonce_str = CheckUtil.create_nonce_str();
            String timestamp = CheckUtil.create_timestamp();
            String jsapi_ticket = getJsApiTicket();
            String string1 = CheckUtil.getString1(nonce_str,timestamp,jsapi_ticket,url);
            String signature = CheckUtil.getSha1(string1);
            ret.put("appid", WXConstants.APPID);//取你自己的公众号appid
            ret.put("url", url);
            ret.put("jsapi_ticket", jsapi_ticket);
            ret.put("nonceStr", nonce_str);
            ret.put("timestamp", timestamp);
            ret.put("signature", signature);
            logger.info("jsApiSign------url=" + url + "-----jsapi_ticket=" + jsapi_ticket + "--------nonceStr=" + nonce_str + "--------timestamp=" + timestamp + "-------signature=" + signature);
            return ret;
        }
        public static String getJsApiTicket(){
            Map<String,Object> map = JsApiTicketCache.getInstance().getJsApiTicketAndExpiresIn();
            return (String) map.get("jsapi_ticket");
        }
    }

    CheckUtil.java

    public class CheckUtil {
        public static final String  token = "xiaodou"; //开发者自行定义Token
        /**
         * 对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式 (即 key1=value1&key2=value2…)拼接成字符串string1
         * @param nonce_str
         * @param timestamp
         * @param jsapi_ticket
         * @param url
         * @return
         */
        public static String getString1(String nonce_str,String timestamp,String jsapi_ticket,String url){
            //1.定义数组存放nonce_str,timestamp,jsapi_ticket,url
            String[] arr = {"noncestr="+nonce_str,"timestamp="+timestamp,"jsapi_ticket="+jsapi_ticket,"url="+url};
            //2.对数组进行排序
            Arrays.sort(arr);
            //3.生成字符串
            StringBuffer sb = new StringBuffer();
            for(String s : arr){
                sb.append(s);
                sb.append("&");
            }
            sb.deleteCharAt(sb.length()-1);
            return sb.toString();
        }
        public static String getSha1(String str){
            if(str==null||str.length()==0){
                return null;
            }
            char hexDigits[] = {'0','1','2','3','4','5','6','7','8','9',
                    'a','b','c','d','e','f'};
            try {
                MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
                mdTemp.update(str.getBytes("UTF-8"));
                byte[] md = mdTemp.digest();
                int j = md.length;
                char buf[] = new char[j*2];
                int k = 0;
                for (int i = 0; i < j; i++) {
                    byte byte0 = md[i];
                    buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
                    buf[k++] = hexDigits[byte0 & 0xf];
                }
                return new String(buf);
            } catch (Exception e) {
                // TODO: handle exception
                return null;
            }
        }
        public static String create_nonce_str() {
            return UUID.randomUUID().toString();
        }
        public static String create_timestamp() {
            return Long.toString(System.currentTimeMillis() / 1000);
        }
    }

    JsApiTicketCatch.java(对jsapi_ticket的缓存可自行设置,redis或者存到数据库都是可行的)

    /**
     * 缓存ticket
     */
    public class JsApiTicketCache {
        //缓存jsapi_ticket的Map,map中包含jsapiTicket,expiresIn和缓存的时间戳time
        private Map<String, String> map = new HashMap<String,String>();
        private static JsApiTicketCache jsApiTicketCache = null;
        private JsApiTicketCache() { }
        // 静态工厂方法
        public static JsApiTicketCache getInstance() {
            if (jsApiTicketCache == null) {
                jsApiTicketCache = new JsApiTicketCache();
            }
            return jsApiTicketCache;
        }
        public Map<String, String> getMap() {
            return map;
        }
        public void setMap(Map<String, String> map) {
            this.map = map;
        }
        /**
         * 获取 jsapi_ticket expires_in
         * @return
         */
        public Map<String,Object> getJsApiTicketAndExpiresIn() {
            Map<String,Object> result = new HashMap<String,Object>();
            JsApiTicketCache jsApiTicketCache = JsApiTicketCache.getInstance();
            Map<String, String> map = jsApiTicketCache.getMap();
            String time = map.get("time");
            String jsapiTicket = map.get("jsapi_ticket");
            String expiresIn = map.get("expires_in");
            Long nowDate = new Date().getTime();
            if (jsapiTicket != null && time != null && expiresIn!=null) {
                //这里设置过期时间为微信规定的过期时间减去5分钟
                int outTime = (Integer.parseInt(expiresIn)-300) * 1000;
                if (nowDate - Long.parseLong(time) < outTime) {
                    System.out.println("-----从缓存读取jsapi_ticket:" + jsapiTicket);
                    //从缓存中拿数据为返回结果赋值
                    result.put("jsapi_ticket", jsapiTicket);
                    result.put("expires_in", expiresIn);
                }
            } else {
                JsapiTicket info = WeiXinUtil.getjsapiTicket();//实际中这里要改为你自己调用微信接口去获取jsapi_ticket和expires_in
                System.out.println("-----通过调用微信接口获取jsapi_ticket:" + info.getJsapiTicket());
                //将信息放置缓存中
                map.put("time", nowDate + "");
                map.put("jsapi_ticket", info.getJsapiTicket());
                map.put("expires_in", info.getExpiresIn()+"");
                //为返回结果赋值
                result.put("jsapi_ticket", info.getJsapiTicket());
                result.put("expires_in", info.getExpiresIn());
            }
            return result;
        }
    
    }

    WeiXinUtil.java

    jsapi_ticket_url="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";//GET方式请求获得jsapi_ticket
     /**
         * 获取jsapi_ticket
         * @return
         */
        public static JsapiTicket getjsapiTicket() {
            JsapiTicket jsapiTicket = null ;
            String accessToken = (String) AccessTokenCache.getInstance().getAcessTokenAndExpiresIn().get("access_token");
            String requestUrl = WXConstants.jsapi_ticket_url.replace("ACCESS_TOKEN", accessToken);
            JSONObject jsonObject = httpRequest(requestUrl, "GET", null);
            // 如果请求成功
            if (null != jsonObject) {
                try {
                    jsapiTicket = new JsapiTicket();
                    jsapiTicket.setJsapiTicket(jsonObject.getString("ticket"));
                    jsapiTicket.setExpiresIn(jsonObject.getInt("expires_in"));
                } catch (JSONException e) {
                    jsapiTicket = null;
                    // 获取token失败
                    log.error("获取ticket失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
                }
            }
            return jsapiTicket;
        }

    accessToken的获取参照微信公众号开发之获取access_token,也可根据自己的定义获取。

    JsapiTicket.java

    public class JsapiTicket {
        private String id;
        private String jsapiTicket;
        private int expiresIn;
    
        public String getJsapiTicket() {
            return jsapiTicket;
        }
    
        public void setJsapiTicket(String jsapiTicket) {
            this.jsapiTicket = jsapiTicket;
        }
    
        public int getExpiresIn() {
            return expiresIn;
        }
    
        public void setExpiresIn(int expiresIn) {
            this.expiresIn = expiresIn;
        }
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    }

    在这里总结一下开发中需要注意的地方(我遇到的坑):

    1.确认url是页面完整的url(请在当前页面alert(location.href.split('#')[0])确认),包括'http(s)://'部分,以及'?'后面的GET参数部分,但不包括'#'hash后面的部分。

    2.在生成string1时,拼接的参数均为小写,特别注意noncestr,而在jsp页面中为nonceStr(所有的参数一定要根据微信接口中的定义,否则会导致验签失败)。

    3.验证签名是否正确,可在 http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign页面工具进行校验。

    展开全文
  • 微信开放实战--扫一扫功能(详细)

    万次阅读 2017-12-14 23:44:27
    大概流程: 1.根据appId和app...进入微信公众平台码登录测试号公众号:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login public static JSONObject getTokenTool(String appId,String appSecr
    大概流程:
    1.根据appId和appSecret获取access_token(使用凭证)
    进入微信公众平台扫码登录测试号公众号:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login

    public static JSONObject getTokenTool(String appId,String appSecret){
    String url="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appId+"&secret="+appSecret;
    System.out.println(HttpRequestUtil.httpRequest(url, "GET", ""));
    return HttpRequestUtil.httpRequest(url, "GET", "");
    }

    这是测试号获取access_token的接口,普通公众号接口地址请查看微信官方文档。



    2.根据access_token获取jsapi_ticket
    public static JSONObject getTicketTool(String access_token){
    String url="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+access_token+"&type=jsapi";
    System.out.println(HttpRequestUtil.httpRequest(url, "GET", ""));
    return HttpRequestUtil.httpRequest(url, "GET", "");
    }





    3.在微信获取签名算法(具体如下)
    public static Map<String, String> sign(String url) {
    String appId="wxcc42f613dbf7299f";
    String appSecret="e59e10c74c70b1c042b5ecaf454052ac";
    String access_token=getTokenTool(appId, appSecret).getString("access_token");
    JSONObject ticketJson=getTicketTool(access_token);
    System.out.println(ticketJson.toString());
    String jsapi_ticket = ticketJson.getString("ticket");
    Map<String, String> ret = new HashMap<String, String>();
    //这里的jsapi_ticket是获取的jsapi_ticket。
    String nonce_str = create_nonce_str();
    String timestamp = create_timestamp();
    String string1;
    String signature = "";
    System.out.println(2);

    //注意这里参数名必须全部小写,且必须有序
    string1 = "jsapi_ticket=" + jsapi_ticket +
    "&noncestr=" + nonce_str +
    "&timestamp=" + timestamp +
    "&url=" + url;

    try
    {
    MessageDigest crypt = MessageDigest.getInstance("SHA-1");
    crypt.reset();
    crypt.update(string1.getBytes("UTF-8"));
    signature = byteToHex(crypt.digest());
    System.out.println("crypt="+crypt.toString());
    System.out.println("string1="+string1);
    System.out.println("signature="+signature);
    }
    catch (NoSuchAlgorithmException e)
    {
    e.printStackTrace();
    }
    catch (UnsupportedEncodingException e)
    {
    e.printStackTrace();
    }

    ret.put("url", url);
    ret.put("jsapi_ticket", jsapi_ticket);
    ret.put("nonceStr", nonce_str);
    ret.put("timestamp", timestamp);
    ret.put("signature", signature);

    return ret;
    }

    private static String byteToHex(final byte[] hash) {
    Formatter formatter = new Formatter();
    for (byte b : hash)
    {
    formatter.format("%02x", b);
    }
    String result = formatter.toString();
    formatter.close();
    return result;
    }

    private static String create_nonce_str() {
    return UUID.randomUUID().toString();
    }

    private static String create_timestamp() {
    return Long.toString(System.currentTimeMillis() / 1000);
    }

    4.获取一个js安全域名接口(如:gstz.imwork.net
    一般使用花生壳进行内网穿透,使内网地址映射到一个花生壳提供的公网的地址,适合用来测试,花生壳内网穿透如何使用可到花生壳官网查看。





    5.把域名和action的地址拼接起来成url,放入签名方法中


    @Controller
    @SuppressWarnings("serial")
    public class WeixinAction{
    /**
    * 获取签名算法
    */
    @RequestMapping("getSign")
    @ResponseBody
    public JSONObject getSign(){
    JSONObject jsonObject=new JSONObject();
    String url="http://17j62137x0.imwork.net/ssm_d1/index.jsp";
    Map<String, String> ret =WxJSUtil.sign(url);
    System.out.println("map="+ret.toString());
    jsonObject.put("weixin", ret);
    System.out.println("json="+jsonObject.toString());
    return jsonObject;
    }
    }
    6.在JSP页面初始化时异步获取签名action传来3个参数,JSP内容如下




    <%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <!DOCTYPE>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>微信扫一扫</title>
    <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
    <script type="text/javascript" src="js/jquery-3.2.1.min.js"></script>
    <script type="text/javascript" src="js/weixin.js"></script>
    </head>
    <body>
    <input id="timestamp" type="hidden" value="${timestamp}" />
    <input id="noncestr" type="hidden" value="${nonceStr}" />
    <input id="signature" type="hidden" value="${signature}" />
    <input id="id_securityCode_input">
    <button id="scanQRCode" οnclick="getWeixinResult()">扫码</button>
    </body>
    <script type="text/javascript">
    </script>
    </html>
    7.通过签名算法获取wx.config的4个重要参数:jsapi_ticket、noncestr、timestamp、url
    wx.config({ debug: true,// 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId:'',// 必填,公众号的唯一标识 timestamp: ,// 必填,生成签名的时间戳 nonceStr:'',// 必填,生成签名的随机串 signature:'',// 必填,签名,见附录1 jsApiList: []// 必填,需要使用的JS接口列表,所有JS接口列表见附录2});



    8.告诉微信选择调用的接口名称



    9.把获取的结果result进行处理getWeixinResultCallBack(param)


    10.给按钮添加 getWeixinResult事件,就可以通过按钮调用扫一扫功能。(记得用微信浏览器点开)


    这是DEMO的下载地址(博主本想免费分享这个资源的,无奈CSDN最少也要2点资源分才能下载):下载DEMO
    展开全文
  • 网页中实现微信扫一扫,不用备案就能在自己网页中实现扫描二维码 有时我们只需要在自己网页中加入个扫一扫并且获取结果的小小功能就行,然而微信开发门槛太高,需要公众号需要交300块认证,然后域名还要备案,...
  • 这里先大概概述一下主要的流程,首先,使用微信扫一扫需要一个已经通过认证的公众号;其次,需要知道公众号的APPID以及APPSecrect,以便获取Access_Token和Ticket;再有就是需要了解.NET内部的SHA1的加密类;最后...

     首先在调用微信的JS-SDK接口的时候需要仔细阅读一下官方的注意事项,否则可能事倍功半。这里先大概概述一下主要的流程,首先,使用微信扫一扫需要一个已经通过认证的公众号;其次,需要知道公众号的APPID以及APPSecrect,以便获取Access_Token和Ticket;再有就是需要了解.NET内部的SHA1的加密类;最后引用官方的JS,就可以了。

    VIEW代码

    需要注意的是,公众号一定要有域名绑定

    复制代码
    <!DOCTYPE html>
    
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>Index</title>
        <script src="http://res.wx.qq.com/open/js/jweixin-1.1.0.js"> </script> 
        <script src="http://libs.baidu.com/jquery/2.0.0/jquery.js"></script>
        <script src="~/Script/WxScanQRCode.js"></script>
        <script>
            wx.config({
            debug: true, // 开启调试模式,调用的所有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 () {
                    var _scan = document.getElementById("url");
                    _scan.value = window.location.href;
                    wx.scanQRCode({
                        needResult: 1,
                        desc: 'scanQRCode desc',
                        success: function (res) {
                            alert(JSON.stringify(res));
                        }
                    });
                })
            }
        </script>
    </head>
    
    <body>
        <div>
            <input type="text" name ="url" id="url">
            <button id="scanbutton" type="button" οnclick="scan()">click here to scan</button>
        </div>
    </body>
    </html>
    复制代码

     

    Controller代码

     

    首先,我们需要根据APPID和APPSecrect来获取Access_Token,之后根据AccessToken来获取jsapi_ticket。最后,在Controller内部生成时间戳,随机字符串,之后将ticket以及前两者根据SHA1加密成签名,并发送给微信服务器,通过认证之后,这样就可以调用扫一扫的接口了。

    复制代码
    public ActionResult Index()
            {
                //获取ACCESS_TOKEN
                string _url = Request.Url.ToString();
                //获取Ticket
                string _ticket = Requestjsapi_ticket(Request_Url());
                //获取ticket
                string _finalticket = _ticket;
                //获取noncestr
                string _noncestr = CreatenNonce_str();
                //获取timestamp
                long _timestamp = CreatenTimestamp();
                //获取sinature
                string _sinature = GetSignature(_finalticket, _noncestr, _timestamp, _url).ToLower();
    
                ViewBag.appid = "这里填写你的APPID";
                ViewBag.timestamp = _timestamp;
                ViewBag.noncestr = _noncestr;
                ViewBag.sinature = _sinature;
                return View();
    
            }
    
    //获取AccessToken
            public static string Request_Url()
            {
                // 设置参数
                string _appid = "这里写入你的APPID";
                string _appsecret = "这里写入你的APPSecrect";
                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");
    
                //发送请求并获取相应回应数据
                HttpWebResponse response = request.GetResponse() as HttpWebResponse;
                //直到request.GetResponse()程序才开始向目标网页发送Post请求
                Stream responseStream = response.GetResponseStream();
                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");
                //发送请求并获取相应回应数据
                HttpWebResponse response = request.GetResponse() as HttpWebResponse;
                //直到request.GetResponse()程序才开始向目标网页发送Post请求
                Stream responseStream = response.GetResponseStream();
                StreamReader sr = new StreamReader(responseStream, Encoding.UTF8);
                //返回结果网页(html)代码
                string content = sr.ReadToEnd();
                //同样,返回的JSON中只要取出ticket的信息即可
                String[] str = content.Split('"');
                content = str[9];
                return content;
            }
    
    //接下来就是辅助工具类,生成随机字符串
    #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
    复制代码

    总结

    代码复制即可使用,需要注意的还是公众号的认证,域名的绑定,以及最后加密算法生成的字符串的正确性,少了哪一步,我们都不会得到一个正确的返回结果。

    转载:https://blog.csdn.net/SugaryoTT/article/details/78558105

    转载于:https://www.cnblogs.com/macT/p/11579449.html

    展开全文
  • 微信扫一扫

    2018-12-20 16:47:33
    主要是调用微信接口比较简单,难点在于签名的验证 前端: &lt;% String openid=null; openid=request.getParameter("openid"); String url="http://cubm67.natappfree.c...

    研究时间:2 day
    主要是调用微信接口比较简单,难点在于签名的验证

    前端:

                <% 
          
            String openid=null;
            openid=request.getParameter("openid");
            
          
          String url="http://cubm67.natappfree.cc//Weixin/test.do";
                  
           Map<String,String> map=JsSignUtil.sign(url); 
               	  
            String username=null;
            String password=null;
          
             String appid="appid";
             String secret="secret"; 
              
             if(openid!=null){
              username=Update.query_loginname(openid);
              if(username==null){
                     response.sendRedirect("login.do"); 
                 }
    		  password=Update.query_password(openid);
             }
    		   
            if(username==null||password==null){
                System.out.println("over_wxsys");
            }                              
                  %>
                  
    <html>
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
        <meta charset="UTF-8">
        <title>扫一扫</title>
        
     <script src="http://libs.baidu.com/jquery/2.0.0/jquery.js"></script>
        <script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
        <script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
        <script  type="text/javascript">
       /*   var signature= document.getElementById('signature').value; */
           
            wx.config({
                debug: false,
                appId: "<%=map.get("appId")%>",
                timestamp:"<%=map.get("timestamp")%>",
                nonceStr:"<%=map.get("nonceStr")%>",
                signature:"<%=map.get("signature")%>",
                jsApiList : ['checkJsApi','scanQRCode']
            });//end_config
            //步骤五
            wx.error(function(res) {
                alert("出错了:" + res.errMsg);
            });
            //步骤四
          wx.ready(function(){
                wx.checkJsApi({
                    jsApiList : ['scanQRCode'],
                    success : function(res) {
                    if(res.checkResult.scanQRCode != true){
                     alert('抱歉,当前客户端版本不支持扫一扫');
                    }
                    }
                });
     
                //扫描二维码
                var url=location.href.split('#')[0];
                //alert(url)
                document.querySelector('#scanQRCode').onclick=function(){ 
                    wx.scanQRCode({
                        needResult : 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
                        scanType : [ "qrCode", "barCode" ], // 可以指定扫二维码还是一维码,默认二者都有
                        success : function(res) {
                            var result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果
                            //document.getElementById("wm_id").value = result;//将扫描的结果赋予到jsp对应值上
                            //alert("扫描成功::扫描码=" + result);
                                                 
                             var obj = JSON.parse(result);       
                             var username="<%=username%>"
                             var password="<%=password%>"  
                                          
                           self.location="http:"+obj.systemCode+
                          "&terminalCode="+obj.terminalCode+
                          "&username="+username+
                          "&password="+password+"";                                    
                        }
                    });
                };    //end_document_scanQRCode
            });//end_ready 
            
            // alert(location.href.split('#')[0]);
        </script>
    </body>
         <div style="margin-top:20px;text-align: center;">
     <button id="scanQRCode" style="border-radius:5px;margin:20px auto;width:80%;height:40px;line-height:40px;text-align:center;background:#66FF66;color:#000;">
           <font size=4>扫描二维码</font></button>
    </body>
    </html>
    

    签名方法:

    import net.sf.json.JSONObject;
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    import java.util.Formatter;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.UUID;
     
    /**
     * 官方给的使用js的验证工具
     * @author Gang_Luo
     *
     */
    
    public class JsSignUtil {
        public static String accessToken = null;
        
     
        public static void main(String[] args) throws IOException {
    		
        	
        	// Map<String, String> map=sign("sy7sqz.natappfree.cc"); 
    
    	}
       
        public static String  getAccessToken() {
        	 JSONObject accesTokenObject;
        	 String accesToken=null;
    		try {
    			 accesTokenObject = AuthUtil.doGetJson(Constants.ACCESS_TOKEN_URL);
    			 accesToken=(String) accesTokenObject.get("access_token");
    		      System.out.println("微信返回accesTokenObject"+accesTokenObject);
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
           
    	
         	 return accesToken;
        }
        
        public static String  getTicket(String accesToken)  {
             accesToken=getAccessToken();
            JSONObject jsapiTicketObject;
             String jsapiTicket=null;
    		try {
    			 jsapiTicketObject = AuthUtil.doGetJson("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + accesToken + "&type=jsapi");
    		     jsapiTicket = (String) jsapiTicketObject.get("ticket"); 
    		     System.out.println("微信返回jsapiTicketObject"+jsapiTicketObject);
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
           
    	
        	 return  jsapiTicket;
       }
        
        public static Map<String, String> sign(String url) throws IOException {
       
        	
        	 TokenSingleton tokenSingleton=TokenSingleton.getInstance();
        	 Map<String, String> map=tokenSingleton.getMap();
    
        	
             String jsapiTicket =map.get("jsapi_token"); 
          
            Map<String, String> ret = new HashMap<String, String>();
            String nonce_str =create_nonce_str();
            String timestamp =create_timestamp();
            String string1;
            String signature ="";
     
            //注意这里参数名必须全部小写,且必须有序
            string1="jsapi_ticket=" + jsapiTicket +
                    "&noncestr=" + nonce_str +
                    "&timestamp=" + timestamp +
                    "&url=" +url;
            try
            {
                MessageDigest crypt = MessageDigest.getInstance("SHA-1");
                crypt.reset();
                crypt.update(string1.getBytes("UTF-8"));
                signature = byteToHex(crypt.digest());
            }
            catch (NoSuchAlgorithmException e)
            {
                e.printStackTrace();
            }
            catch (UnsupportedEncodingException e)
            {
                e.printStackTrace();
            }
     
            ret.put("url", url);
            ret.put("jsapi_ticket",jsapiTicket);
            ret.put("nonceStr", nonce_str);
            ret.put("timestamp", timestamp);
            ret.put("signature", signature);
            ret.put("appId", "appId");
     
     
           //System.out.println("JsSignUtil.url="+ret.get("url"));
         /*  
          *  System.out.println("1.ticket(原始)="+jsapiTicket);
            System.out.println("4.nonceStr="+ret.get("nonceStr"));
            System.out.println("5.signature="+ret.get("signature"));
            System.out.println("6.timestamp="+ret.get("timestamp"));*/
    
            return ret;
        }
     
     
        /**
         * 随机加密
         * @param hash
         * @return
         */
        private static String byteToHex(final byte[] hash) {
            Formatter formatter = new Formatter();
            for (byte b : hash)
            {
                formatter.format("%02x", b);
            }
            String result = formatter.toString();
            formatter.close();
            return result;
        }
     
        /**
         * 产生随机串--由程序自己随机产生
         * @return
         */
        private static String create_nonce_str() {
            return UUID.randomUUID().toString();
        }
     
        /**
         * 由程序自己获取当前时间
         * @return
         */
        private static String create_timestamp(){
            return Long.toString(System.currentTimeMillis() / 1000);
        }
    }
    
    

    注意:

      **签名url与调用接口的url必须完全一样!!!!在这里卡了一个下午!!!**
    

    服务器配置:

    服务器地址:servlet 令牌(Token):god
    签名校验

      public static boolean checkSignature(String signature, String timestamp, String nonce)
      {
        String[] arr = { "god", timestamp, nonce };
        if ((timestamp != null) && (nonce != null)) {
          Arrays.sort(arr);
        }
    
        StringBuffer content = new StringBuffer();
        for (int i = 0; i < arr.length; i++)
        {
          content.append(arr[i]);
        }
    
        String temp = getSha1(content.toString());
    
        return temp.equals(signature);
      }
    

    微信后台操作:

    import com.imooc.util.CheckUtil;
    import com.imooc.util.MesssageUtil;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.Map;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class WeixinServlet extends HttpServlet
    {
      private static final long serialVersionUID = 1L;
    
      protected void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException
      {
        String signature = req.getParameter("signature");
        String timestamp = req.getParameter("timestamp");
        String nonce = req.getParameter("nonce");
        String echostr = req.getParameter("echostr");
    
        PrintWriter out = resp.getWriter();
        if (CheckUtil.checkSignature(signature, timestamp, nonce))
          out.print(echostr);
      }
    
      protected void doPost(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException
      {
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        PrintWriter out = resp.getWriter();
    
        Map map = MesssageUtil.xmlToMap(req);
    
        String toUserName = (String)map.get("ToUserName");
        String fromUserName = (String)map.get("FromUserName");
        String msgType = (String)map.get("MsgType");
        String content = (String)map.get("Content");
    
        String msg = "";
        if ("text".equals(msgType))
        {
          if ("1".equals(content)) {
            msg = MesssageUtil.initText(fromUserName, toUserName, MesssageUtil.firstmenu());
          }
        }
        else if ("event".equals(msgType))
        {
          String eventTpye = (String)map.get("Event");
          if ("subscribe".equals(eventTpye))
          {
            msg = MesssageUtil.initText(fromUserName, toUserName, MesssageUtil.menuText());
          } else if ("CLICK".equals(eventTpye)) {
            String eventKey = (String)map.get("EventKey");
    
            if (eventKey.equals("zzzzzzzzzzzzz"))
            {
              msg = MesssageUtil.initText(fromUserName, toUserName, MesssageUtil.firstmenu());
            }
          }
        }
        out.print(msg);
        out.close();
      }
    }
    
    展开全文
  • 微信扫一扫调用

    2019-07-30 10:48:45
    1去微信公众平台配置 2 controller中的方法 (没有工具类的参考我另篇)https://blog.csdn.net/qq_42917455/article/details/97751644 /** * 调用微信二维码的方法 * @param request * @return * @throws ...
  • 利用微信JSSDK调用微信扫一扫功能

    万次阅读 2017-07-25 03:44:42
    1. 确保有 调起微信扫一扫接口 权限,测试号可能不行; 2. 导入相关JS 3. 页面触发扫码元素 4. 相关JS代码 var _appId = "wxz88dbd30e5580e59"; var _data = { appId : _appId, url : location.href, ...
  • 微信扫一扫登录网站

    千次阅读 2019-04-26 10:22:43
    微信网站扫一扫登录 标签(空格分隔): wechat 科普微信授权原理 Created with Raphaël 2.1.2微信用户微信用户第三方应用第三方应用微信开发平台微信开发平台第三方应用第三方应用微信开发平台微信开发...
  • 调用范例完整代码下载: ... csdn的这个博文写的有点啰嗦,建议移步...在网页上点一个按钮或者链接调用微信扫一扫然后返回结果我们继续处理,很多人应该都会有这样的需求,不过微信对这个空子比较严格,需要你的网页...
  • 使用JS-SDK调用微信扫一扫,需要有公众号支持,通过公众号生成JS-SDK使用权限签名。本文直接调用已封装好的接口来获取随机数(noncestr)、时间戳(timestamp)、签名(signature),接口地址:...
  • 微信公众号开发之微信扫一扫

    千次阅读 2019-05-27 22:32:59
    最近开发一个食堂项目,项目中用到使用微信扫一扫实现项目中的扫一扫的功能。 1、添加点击扫一扫的触发事件的按钮 <span id="scanQRCode">扫一扫</span> 2、添加微信扫一扫的js引用 <script ...
  • 根据微信api,整理了一下调用微信扫一扫功能。如有问题请指正: 以下是具体步骤: 1、绑定域名(很关键)2、引入JS文件(很简单) script src="http://res.wx.qq.com/open/js/jweixin-1.1.0.js">script>3、通过...
  • Java调用微信扫一扫

    千次阅读 热门讨论 2019-07-24 18:49:48
    公司公众号二次开发需要调用微信扫一扫接口,在网上查了很多相关资料感觉也不是特别的全,在此特意整理一遍资料,供给自己和大家参考,如有相关缺陷请大家指出。 步骤一:绑定域名 ...id=mp1421141115打开微信官方...
  • C#、.NET 调用微信扫一扫接口完整demo,非常实用,已封装好微信扫一扫的接口
  • 近来对于微信扫一扫打印照片十分的感兴趣,觉得挺有意思的。对于软件编程以及连接打印机等硬件方面的知识都有所涉及,故实现这样的的微信扫一扫打印照片的功能。 分析如下: 微信扫一扫首先设计二维码的生成和获取...
  • H5如何拉起微信扫一扫

    万次阅读 2018-03-19 10:57:22
    扫一扫功能 项目开发中有很多场景需要拉起微信扫一扫,在这里主要记录下开发过程中遇到的一些问题,以及解决方案。仅供参考 拉起方法 官方的sdk文档关于使用方法写的很详细 ...基本上对照官方文档的做法都能完成 ...
  • vue h5 调微信扫一扫 简单实用 1.第一步绑定域名,就是你在公众号登录之后要设置域名,还有白名单,这个喊后端去弄,前端又不晓得哪些是白名单,域名是好多 2.第二步:安装js-sdk的包(用npm 或yarn安装npm install ...
  • Java实现微信扫一扫

    千次阅读 2016-12-27 17:44:07
    这两周做了项目关于微信端的处理,主要是实现调起微信扫一扫和通过微信获取地理位置。写在前面,不要急,这些东西对第一次开发微信端的人来说很重要: 不太善于布局,大家凑合看,主要看内容哈 我先详细的解释一些...
  • 微信JSSDK实现微信自定义分享,微信扫一扫 前言: 由于微信使用的越来越多,也让大多数平台或者APP与微信建立了比较深的合作关系,我们公司自主研发的产品也是比较依赖于微信,最近也写了几篇关于微信的博客,本文...
  • UNI-APP 开发微信公众号(H5)JSSDK的使用、微信扫一扫 自己做了一个h5端调起微信扫一扫的功能,上网一找,没有说得很详细的,依样画葫芦,结果出了很多问题。下面给大家讲一下做的方法,用这个方法亲测有效。 在做...
1 2 3 4 5 ... 20
收藏数 70,277
精华内容 28,110
关键字:

微信扫一扫