微信JSSDK使用签名算法

第一步:绑定域名

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

第二步:引入js文件

在页面里引入微信的jssdk文件:http://res.wx.qq.com/open/js/jweixin-1.2.0.js

第三步:调用config接口注入权限

整体就是页面通过ajax请求后台生成签名,将生成的签名和生成签名时用的参数返回,在通过wx.config接口调用验证,这个验证大概就是微信拿到wx.config接口你配的参数也生成一个签名,然后和你生成的签名比较,一样验证成功,不一样验证失败。

 前台:

$(function() {
	var data = {};
	data.htmlUrl = location.href.split('#')[0];
	$.ajax({
		url: SUrl+"/wechatUtils/getSignature",
		type: 'post',
		dataType: 'json',
		contentType: "application/json;charset=utf-8",
		data: JSON.stringify(data),
		success: function(data) {
			debugger
			if(data.resCode == "200") {
				wx.config({
					debug:true,
					appId: data.obj.appid,
					timestamp: data.obj.timestamp,
					nonceStr: data.obj.noncestr,
					signature: data.obj.signature,
					jsApiList: [
						'scanQRCode'
					]
				});
			}
		},
		error: function(jqXHR, textStatus, errorThrown) {
			if(textStatus == "timeout") {
				uTip.showDialog({
					"tip_content": "连接超时,请检查网络"
				});
			} else {
				uTip.showDialog({
					"tip_content": "加载失败,请稍后再试"
				});
			}
		}
	});

	wx.ready(function() {
		wx.checkJsApi({
			jsApiList: ['scanQRCode'],
			success: function(res) {
				if(res.checkResult.scanQRCode) {
					return true;
				} else {
					mui.toast('您的设备不支持扫码!');
				}
			}
		});
	});

	wx.error(function(res) {
		mui.toast('初始化失败!');
	});
});
wx.config验证成功会执行wx.ready里面的代码,我这里主要就是执行了wx.checkJsApi,这就是验证当前的设备是否支持扫二维码的功能。如果进入wx.error,就是wx.config验证失败了。具体的接口内容可以查看微信公众平台文档。

后台:controller

package com.xtpt.frontend.modules.wechat.web;

import java.util.HashMap;
import java.util.Map;

import com.lpcode.modules.dto.wechat.WxAccessTokenDto;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONObject;
import com.framework.core.result.Result;
import com.framework.osp.common.utils.JedisClusterUtils;
import com.lpcode.modules.dto.wechat.WxJsapiTicketDto;
import com.lpcode.modules.dto.wechat.WxSignatureDto;
import com.lpcode.modules.dto.wechat.WxTemplateMessageDto;
import com.lpcode.modules.service.impl.wechat.WeChatUtilsServiceImpl;
import com.xtpt.frontend.util.wechat.WeChatUtils;

@Controller
@RequestMapping(value="/wechatUtils")
public class WxUtilsController {
    private static final String NONCESTR = "szrq";

    @Value("${wechat.appid}")
    private String appid;
    @Value("${wechat.appsecret}")
    private String appsecret;

    @ResponseBody
    @RequestMapping(value="/getSignature" ,method = RequestMethod.POST,produces = "application/json;charset=UTF-8", consumes = "application/json;charset=UTF-8")
    public Result<WxSignatureDto> getSignature(@RequestBody JSONObject requestObject){
        Result<WxSignatureDto> result = new Result<WxSignatureDto>();
        WxSignatureDto signatureDto = new WxSignatureDto();
        String timestamp = (System.currentTimeMillis() / 1000) + "";
        signatureDto.setTimestamp(timestamp);
        signatureDto.setAppid(appid);
        signatureDto.setNoncestr(NONCESTR);
        String accessToken = WeChatUtils.getAccessToken(appid, appsecret).getAccesstoken();    //获取access_token
        String jsapiTicket = WeChatUtils.getJsapiTicket(accessToken).getJsapiticket();         //获取jsapi_ticket
        signatureDto.setSignature(WeChatUtils.getSignature(timestamp, NONCESTR, requestObject.getString("htmlUrl"), jsapiTicket)
		result.setResCode("200");
        result.setMsg("签名成功");
        result.setObj(signatureDto);

        return result;
    }
}

签名时是需要jsapi_ticket的,这个值是调用微信接口获取的,这个接口入参需要access_token。

access_token是通过调用微信调口获取的,这个接口入参需要appid和appsecret(微信公众号里的基本配置里可以拿到)。

后台:WeChatUtils.getSignature()生成签名的方法

 public static String getSignature(String timestamp, String nonceStr, String url, String jsapiTicket) {
        MessageDigest md = null;
        String string1 = "jsapi_ticket=" + jsapiTicket
                + "&noncestr=" + nonceStr + "×tamp=" + timestamp + "&url="
                + url;

        String signature = "";
        try {
            md = MessageDigest.getInstance("SHA");
            byte[] digest = md.digest(string1.getBytes());
            signature = byteToStr(digest);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return signature;
    }

这个方法就是把timestamp, nonceStr,url,jsapiTicket拼接起来生一个SHA的签名,这里注意,这几个参数不是随便拼接的,是根据参数key首字母a-z拼接的,因为参数位置不一样生成的签名也是不一样的,我这里是正确的顺序。

后台:依赖方法

    private static String byteToStr(byte[] digest) {
        String strDigest = "";
        for (int i = 0; i < digest.length; i++) {
            strDigest = strDigest + byteToHexStr(digest[i]);
        }
        return strDigest;
    }

第四步:config验证成功会执行ready

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

评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值