微信如何搭建本地测试环境

微信不得不说对程序员非常不友好,开发复杂,各种验证,各种扫一扫。

比如开发一个简单的html,想分享到朋友圈一下下,结果还要后台生成jsTicket和签名,jsTicket又依赖access_token,access_token又得缓存起来,简直就是醉了。为了防止微信成为另一个qq空间,弄的复杂的要死,不过也阻止不了成为另一个qq空间。

首先描述一下需求:做了一个静态的html,需要分享时自定义图片,和描述文字。

解决方法:各种查文档,最后思路为需要后台支撑,后台要获取jsTicKet,jsTicket需要access_token,两者都需要做缓存。后台语言为java,采用的wexin开发包为: weixin-popular  https://github.com/liyiorg/weixin-popular .微信文档: https://mp.weixin.qq.com/wiki/11/74ad127cc054f6b80759c40f77ec03db.html 

实现java主要实现类,access_token采用TokenManager,自带了超时刷新,可以查看TokenManager源码,用一个定时任务,每隔118分更新一次token。为了快速开发,jsTicket采用的项目带的redis做缓存。

package cn.arvix.ober.service.impl;

import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import cn.arvix.ober.been.JSONResult;
import cn.arvix.ober.consants.ArvixOberConstants;
import cn.arvix.ober.controller.WeixinController;
import cn.arvix.ober.service.WeixinService;
import cn.arvix.ober.util.WeixinJsSign;
import weixin.popular.api.TicketAPI;
import weixin.popular.support.TokenManager;

@Service
public class WeixinServiceImpl implements WeixinService{
	private static String REDIS_WEIXIN_JS_TOKEN = "WEIXIN_JSAPI_TOKEN";
	private static final Logger log = LoggerFactory
			.getLogger(WeixinController.class);
	
	@Autowired
    public RedisTemplate<Object, Object> redisTemplate;
	@Override
	public JSONResult getAccessToken() {
		JSONResult result = new JSONResult();
		String token = TokenManager.getToken(ArvixOberConstants.WH_CHAT_CLIENT_APP_ID);
		log.info("weixin access token--->{}",token);
		result.setSuccess(true);
		result.setData(token);
		return result;
	}

	@Override
	public JSONResult getJsApiToken() {
		JSONResult result = new JSONResult();
		result.setSuccess(true);
		result.setData(getJsApiTokenStr());
		return result;
	}
	private String getJsApiTokenStr(){
		String token = TokenManager.getToken(ArvixOberConstants.WH_CHAT_CLIENT_APP_ID);
		log.info("weixin access token--->{}",token);
		Object cacheJsToken = redisTemplate.opsForValue().get(REDIS_WEIXIN_JS_TOKEN);
		String jsToken = "";
		if(null!=cacheJsToken){
			jsToken = cacheJsToken.toString();
			log.info("get weixin jsToken from cache--->{}",jsToken);
		}else{
			jsToken = TicketAPI.ticketGetticket(token).getTicket();
			log.info("get weixin jsToken from weixin --->{}",jsToken);
			redisTemplate.opsForValue().set(REDIS_WEIXIN_JS_TOKEN, jsToken, 118, TimeUnit.MINUTES);
		}
		return jsToken;
	}

	@Override
	public JSONResult getJsSign(String url) {
		JSONResult result = new JSONResult();
		result.setSuccess(true);
		result.setData(WeixinJsSign.sign(getJsApiTokenStr(), url));
		return result;
	}

}

签名实现类

package cn.arvix.ober.util;

import java.util.UUID;
import java.util.Map;
import java.util.HashMap;
import java.util.Formatter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.io.UnsupportedEncodingException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class WeixinJsSign {
	private static final Logger log = LoggerFactory.getLogger(Email.class);
	public static Map<String, String> sign(String jsapi_ticket, String url) {
		Map<String, String> ret = new HashMap<String, String>();
		String nonce_str = create_nonce_str();
		String timestamp = create_timestamp();
		String signInput;
		String signature = "";
		// 注意这里参数名必须全部小写,且必须有序
		signInput = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce_str
				+ "&timestamp=" + timestamp + "&url=" + url;
		log.info("signInput:{}",signInput);
		try {
			MessageDigest crypt = MessageDigest.getInstance("SHA-1");
			crypt.reset();
			crypt.update(signInput.getBytes("UTF-8"));
			signature = byteToHex(crypt.digest());
		} catch (NoSuchAlgorithmException e) {
			log.error("",e);
		} catch (UnsupportedEncodingException e) {
			log.error("",e);
		}
		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);
	}
}

其它就是暴露一个接口api,提交url做为参数去换取jsApiConfig需要的参数。

重点来了,本地调试:下载 https://mp.weixin.qq.com/wiki/10/e5f772f4521da17fa0d7304f68b97d7e.html 里面的开发者工具,pc端上模拟微信手机端,然后就是域名的问题,js绑定了域名,只有在该域名下的请求,微信才会接收,这里只能是取巧:更改本地hosts文件,让配置的域名指向本地服务,win10参考配置地址:

http://jingyan.baidu.com/article/cbcede073380fb02f40b4d84.html ,其它系统类似。

js示例代码:

var _timestamp='',_nonscestring='',_signature='';
    var url = location.href.split('#')[0]
    $.ajax({
        url:'http://192.168.0.104:9007/api/v1/weixin/getJsSign',
        data:{url:url},
        type:'get',
        async:false,
        success:function(data){
            if(data.success){
                _timestamp=data.data.timestamp;
                _nonscestring=data.data.nonceStr;
                _signature=data.data.signature;
            }
            alert(location.href.split('#')[0])
            alert(_timestamp+","+_nonscestring+","+_signature);
            console.log(_timestamp+","+_nonscestring+","+_signature)
        }
    })
    wx.config({
        debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
        appId: 'wxb42c4e84da6027b6', // 必填,公众号的唯一标识
        timestamp:_timestamp , // 必填,生成签名的时间戳
        nonceStr: _nonscestring, // 必填,生成签名的随机串
        signature: _signature,// 必填,签名,见附录1
        jsApiList: [
            'onMenuShareTimeline',
            'onMenuShareAppMessage',
            'onMenuShareWeibo'
        ] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
    });

测试结果图片:

120754_J2Vu_10803.png

转载于:https://my.oschina.net/asdtiang/blog/776479

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值