博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
002-JS-SDK开发使用,网页获取授权,扫一扫调用
阅读量:6090 次
发布时间:2019-06-20

本文共 11073 字,大约阅读时间需要 36 分钟。

一、概述

在申请响应的公众号之后,实名认证或者企业认证之后,可以进行对应开发

二、开发步骤

2.1、开发前提【服务号】-域名设置

  登录后台之后→左侧设置→公众号设置→功能设置,设置好“JS接口安全域名","网页授权域名"对应域名

  

2.2、开发前提【服务号】-开发者ID设置

  登录后台之后→左侧开发→基本配置→公众号开发信息,设置好“开发者密码(AppSecret)”

2.3、查看接口信息

  登录后台之后→左侧开发→接口权限→查看已开通的接口授权

三、调用示例

JS-SDK

  接口列表: 附录2

  详情页:

3.1、示例一、微信网页授权【】

  1 第一步:用户同意授权,获取code

  2 第二步:通过code换取网页授权access_token

  3 第三步:刷新access_token(如果需要)

  4 第四步:拉取用户信息(需scope为 snsapi_userinfo)

  5 附:检验授权凭证(access_token)是否有效

  1》整体流图

    

  2》详细参看地值

    微信网页授权【】

3.2、示例二、微信JS-SDK说明文档【 或者】

  JSSDK使用步骤【原文地址:】

    步骤一:绑定域名
      先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
      备注:登录后可在“开发者中心”查看对应的接口权限。  

    步骤二:引入JS文件

      在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.2.0.js
      备注:支持使用 AMD/CMD 标准模块加载方法加载

    步骤三:通过config接口注入权限验证配置

      所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)。      

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

      签名算法,支持方法

    步骤四:通过ready接口处理成功验证      

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

    步骤五:通过error接口处理失败验证    

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

  接口调用说明

  所有接口通过wx对象(也可使用jWeixin对象)来调用,参数是一个对象,除了每个接口本身需要传的参数之外,还有以下通用参数:

    1.success:接口调用成功时执行的回调函数。

    2.fail:接口调用失败时执行的回调函数。
    3.complete:接口调用完成时执行的回调函数,无论成功或失败都会执行。
    4.cancel:用户点击取消时的回调函数,仅部分有用户取消操作的api才会用到。
    5.trigger: 监听Menu中的按钮点击时触发的方法,该方法仅支持Menu中的相关接口。

    备注:不要尝试在trigger中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回。

    以上几个函数都带有一个参数,类型为对象,其中除了每个接口本身返回的数据之外,还有一个通用属性errMsg,其值格式如下:
    调用成功时:"xxx:ok" ,其中xxx为调用的接口名
    用户取消时:"xxx:cancel",其中xxx为调用的接口名
    调用失败时:其值为具体错误信息

3.3、示例三、根据2.5.5 以扫一扫为例:

  1》服务器端设置js域名

  2》html页面引用相关js  

  3》界面调用

  4》相关JS代码

jQuery(document).ready(function () {    var getWechatSignUrl = "http://test.com/openapi/wechat/getJsApiSign';    // 获取微信签名    $.ajax({        url: getWechatSignUrl + "?url=" + encodeURIComponent(window.location.href.split('#')[0]),        success: function (o) {            console.log(o);            if (o.code == 20000) {                wxConfig(o.data.appId, o.data.timestamp, o.data.nonceStr, o.data.signature);            }        }, error: function (o) {            alert("出错了" + JSON.stringify(o));        }    });    function wxConfig(_appId, _timestamp, _nonceStr, _signature) {        var mm = '获取数据:' + encodeURIComponent(window.location.href.split('#')[0])            + '\n' + _appId + '\n' + _timestamp + '\n' + _nonceStr + '\n' + _signature;        console.log(mm);        wx.config({            debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。            appId: _appId, // 必填,公众号的唯一标识            timestamp: _timestamp, // 必填,生成签名的时间戳            nonceStr: _nonceStr, // 必填,生成签名的随机串            signature: _signature,// 必填,签名            jsApiList: ["scanQRCode"] // 必填,需要使用的JS接口列表        });    }    function scanCode() {        wx.scanQRCode({            needResult: 1,            scanType: ["qrCode", "barCode"],            success: function (res) {                var result = res.resultStr;                alert(result);            },            fail: function (res) {                console.log(res)                alert(JSON.stringify(res));            }        });    }    //客户端扫码    $("#btnScanCode").click(function () {        scanCode();    });});
View Code

  5》服务器端接口设计

    全局响应枚举类    

public enum ResponseEnum {    //账户类异常10000    USEREXCEPTION(10000, "账户异常"),    SUCCESS(20000, "操作成功"),    //参数类异常 30000    NOTFOUND(30000, "必输参数为空"),    INPUTERROR(30001, "输入参数格式错误"),    DATEERROR(30002, "日期区间错误"),    DATEOUTOF(30003, "日期区间超出范围"),    //系统类未知异常 99999    ERROR(99999, "系统异常"),;    private int code;    private String msg;    ResponseEnum(int code, String msg) {        this.code = code;        this.msg = msg;    }    public int getCode() {        return code;    }    public void setCode(int code) {        this.code = code;    }    public String getMsg() {        return msg;    }    public void setMsg(String msg) {        this.msg = msg;    }    @Override    public String toString() {        return String.format("[%s:%s]", code, msg);    }}
View Code

    全局响应类

public class ResponseResult
{ /** * 方法返回状态码 */ private int code; /** * 方法返回信息 */ private String msg; private T data; public ResponseResult(){ setResponseEnum(ResponseEnum.SUCCESS);} public ResponseResult(ResponseEnum enums){ setResponseEnum(enums); } public ResponseResult(ResponseEnum enums, T data){ setResponseEnum(ResponseEnum.SUCCESS); this.data = data; } public ResponseResult(T data){ this(ResponseEnum.SUCCESS,data); } public void setResponseEnum(ResponseEnum enums){ this.code = enums.getCode(); this.msg = enums.getMsg(); } public int getCode() { return code; } public String getMsg() { return msg; } public T getData() { return data; } public void setData(T data) { this.data = data; }}
View Code

    jsapi结果类

public class JsApiPageDomain {    private String appId; // 必填,公众号的唯一标识    private long timestamp; // 必填,生成签名的时间戳    private String nonceStr; // 必填,生成签名的随机串    private String signature;// 必填,签名    private String[] jsApiList;// 必填,需要使用的JS接口列表    public String getAppId() {        return appId;    }    public void setAppId(String appId) {        this.appId = appId;    }    public long getTimestamp() {        return timestamp;    }    public void setTimestamp(long timestamp) {        this.timestamp = timestamp;    }    public String getNonceStr() {        return nonceStr;    }    public void setNonceStr(String nonceStr) {        this.nonceStr = nonceStr;    }    public String getSignature() {        return signature;    }    public void setSignature(String signature) {        this.signature = signature;    }    public String[] getJsApiList() {        return jsApiList;    }    public void setJsApiList(String[] jsApiList) {        this.jsApiList = jsApiList;    }}
View Code

    获取getJsApiSign

@RequestMapping(value = "/getJsApiSign", method = RequestMethod.GET)    @ResponseBody    public ResponseResult
getJsApiSign(String url) { ResponseResult
result = new ResponseResult<>(); JsApiPageDomain jsApiPageDomain = null; try { //返回页面签名等信息 //时间戳 long timeStamp = System.currentTimeMillis()/1000L; //字母数字随机串 String nonceStr = RandomStringUtils.randomAlphanumeric(16); //获取JsApITicket String jsApiTicket = weChatUtil.getJsApiTicket(); jsApiPageDomain = new JsApiPageDomain(); jsApiPageDomain.setAppId(globalConfig.getWeChatAppID()); jsApiPageDomain.setNonceStr(nonceStr); jsApiPageDomain.setTimestamp(timeStamp); jsApiPageDomain.setSignature(weChatUtil.signature(nonceStr, jsApiTicket, timeStamp, url)); jsApiPageDomain.setJsApiList(new String[]{"scanQRCode"}); result.setData(jsApiPageDomain); } catch (Exception e) { logger.error("getJsApiSign请求异常", e); } return result; }
View Code

    获取基础access_token【】

/**     * 获取access_token     *     * @return     */    public String getAccessToken() {        //redis读取        if (RedisUtil.exist(interfaceAccessTokenKey)) {            String redis = RedisUtil.findValueFromRedis(interfaceAccessTokenKey);            if (StringUtils.isNotBlank(redis)) {                return redis;            }        }        //执行调用        ResponseEntity
entity = restTemplate.getForEntity(globalConfig.getWechatInterfaceAccessToken(), InterfaceAccessToken.class); if (entity != null && entity.getStatusCode() == HttpStatus.OK) { if (entity.getBody() != null&&StringUtils.isNotBlank(entity.getBody().getAccess_token())) { RedisUtil.saveToRedis(interfaceAccessTokenKey, entity.getBody().getAccess_token()); int tmp = entity.getBody().getExpires_in() - (60 * 5); RedisUtil.setExpire(interfaceAccessTokenKey, tmp>0?tmp:1, TimeUnit.SECONDS); return entity.getBody().getAccess_token(); } } return null; }
View Code

    获取jsapi_ticket【 附录1】

/**     * 获取jsapi_ticket     *     * @return     */    public String getJsApiTicket() {        String token = getAccessToken();        if (StringUtils.isBlank(getAccessToken())) {            return null;        }        //redis读取        if (RedisUtil.exist(jsapiTicketKey)) {            String redis = RedisUtil.findValueFromRedis(jsapiTicketKey);            if (StringUtils.isNotBlank(redis)) {                return redis;            }        }        String apiTicket = MessageFormat.format(globalConfig.getWechatJsApiTicket(), token);        //执行调用        ResponseEntity
entity = restTemplate.getForEntity(apiTicket, JsApiTicket.class); if (entity.getStatusCode() == HttpStatus.OK) { if (entity.getBody() != null&&StringUtils.isNotBlank(entity.getBody().getTicket())) { RedisUtil.saveToRedis(jsapiTicketKey, entity.getBody().getTicket()); //过期时间 Long ttl = RedisUtil.ttl(interfaceAccessTokenKey); if (ttl != null && (ttl.longValue() - 1 > 0)) { RedisUtil.setExpire(jsapiTicketKey, ttl.longValue() - 1, TimeUnit.SECONDS); } else { getJsApiTicket(); } return entity.getBody().getTicket(); } } return null; }
View Code

    注意 基础access_token 和 jsapi_ticket 使用为redis缓存,同时具有相同的失效时间

    签名

public String signature(String noncestr, String jsapiTicket, long timestamp, String url) {        TreeMap
map = new TreeMap<>();//以后扩展方便 map.put("noncestr", noncestr); map.put("jsapi_ticket", jsapiTicket); map.put("timestamp", String.valueOf(timestamp)); map.put("url", url); StringBuilder sb = new StringBuilder(); map.forEach((k, v) -> { sb.append(k + "=" + v + "&"); }); String msg = sb.toString().substring(0, sb.length() - 1); System.out.println("加密信息:" + msg); //签名 MessageDigest m = null; try { m = MessageDigest.getInstance("SHA-1"); m.update(msg.getBytes("UTF8")); } catch (Exception e) { e.printStackTrace(); return null; } byte s[] = m.digest(); return Hex.encodeHexString(s); }
View Code

    

  

 

转载地址:http://wmlwa.baihongyu.com/

你可能感兴趣的文章
URL中的特殊字符
查看>>
AOP动态代理解析4-jdk代理的实现
查看>>
5个国外免费图标搜索网站
查看>>
“神似充气娃娃”的人形机器人,made in China
查看>>
strncmp memcmp区别
查看>>
我的第一个python web开发框架(4)——数据库结构设计与创建
查看>>
我有一个梦想,希望每一位提到算法的人,不再立即紧皱眉头
查看>>
KVM添加虚拟机网卡
查看>>
微信支付宝无现金之争:瞄准用户支付大数据
查看>>
https证书验证
查看>>
RIP 路由汇总实验
查看>>
Java性能调优
查看>>
db_recovery_file_dest_size 修改大一点及删除归档日志 |转|
查看>>
.Net Core 使用 Swagger 提供API文档
查看>>
Python时间运算的详细机制初探讨
查看>>
sqlserver数据库的服务器 改名字后 数据库登录不上 解决方案
查看>>
1-6. 文件权限
查看>>
windows 入门试验系列
查看>>
提示Windows Phone IP over USB Transport (IpOverUsbSvc)未运行,如何解决
查看>>
DHCP服务器构建
查看>>