本部分需要用到微信的JS-SDK,微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包。
通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验。
一、JS-SDK引入
1.先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”,和网页授权一样只是个域名。
2.在需要调用JS接口的页面引入如下JS文件之一
二、通过config接口注入权限验证配置
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,公众号的唯一标识
timestamp: , // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '',// 必填,签名
jsApiList: [] // 必填,需要使用的JS接口列表
});
首先生成这个signature之前需要获取到一个临时票据jsapi_ticket,jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,同样也需要个中控服务器控制刷新。
1、获取临时票据
封装返回结果
packagecom.phil.wechatauth.model.resp;importcom.phil.common.result.ResultState;/*** jsapi_ticket是公众号用于调用微信JS接口的临时票据
*@authorphil
* @date 2017年8月21日
**/
public class JsapiTicket extendsResultState {/****/
private static final long serialVersionUID = -357009110782376503L;private String ticket; //jsapi_ticket
privateString expires_in;publicString getTicket() {returnticket;
}public voidsetTicket(String ticket) {this.ticket =ticket;
}publicString getExpires_in() {returnexpires_in;
}public voidsetExpires_in(String expires_in) {this.expires_in =expires_in;
}
}
获取方法
/*** 获取jsapi_ticket 调用微信JS接口的临时票据
*@return
*/
publicString getTicket(String accessToken) {
JsapiTicket jsapiTicket= null;
Map params = new TreeMap();
params.put("access_token",accessToken);
params.put("type", "jsapi");
String result= HttpReqUtil.HttpDefaultExecute(HttpReqUtil.GET_METHOD, WechatConfig.GET_TICKET_URL, params,"");if(StringUtils.isNotBlank(result)){
jsapiTicket= JsonUtil.fromJson(result, JsapiTicket.class);
}if(jsapiTicket.getErrcode()==0){returnjsapiTicket.getTicket();
}return null;
}
2、生成签名并返回参数
signature生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。
string1示例如下
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW×tamp=1414587457&url=http://mp.weixin.qq.com?params=value
这里有个坑,页面是nonceStr,但是签名的字段是noncestr,注意大小写
简单封装下JS-SDK config配置信息
packagecom.phil.wechatauth.model.resp;/*** JS-SDK的页面配置信息
*@authorphil
* @date 2017年8月22日
**/
public classJsWechatConfig {privateString appId;private longtimestamp;privateString noncestr;privateString signature;publicString getAppId() {returnappId;
}public voidsetAppId(String appId) {this.appId =appId;
}public longgetTimestamp() {returntimestamp;
}public void setTimestamp(longtimestamp) {this.timestamp =timestamp;
}publicString getNoncestr() {returnnoncestr;
}public voidsetNoncestr(String noncestr) {this.noncestr =noncestr;
}publicString getSignature() {returnsignature;
}public voidsetSignature(String signature) {this.signature =signature;
}
}
添加配置信息到页面
/****/
packagecom.phil.wechatauth.controller;importjava.util.SortedMap;importjava.util.TreeMap;importjavax.servlet.http.HttpServletRequest;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Controller;importorg.springframework.web.bind.annotation.RequestMapping;importcom.phil.common.config.SystemConfig;importcom.phil.common.config.WechatConfig;importcom.phil.common.util.DateTimeUtil;importcom.phil.common.util.PayUtil;importcom.phil.common.util.SignatureUtil;importcom.phil.wechatauth.model.resp.JsWechatConfig;importcom.phil.wechatauth.service.WechatAuthService;/*** JS-SDK
*@authorphil
* @date 2017年8月21日
**/@Controller
@RequestMapping("/auth")public classWechatAuthController {
@AutowiredprivateWechatAuthService wechatAuthService;/*** 获取地理位置
*@paramrequest
*@return*@throwsException*/@RequestMapping("/getLocation")public String getLocation(HttpServletRequest request) throwsException{
JsWechatConfig jsWechatConfig= newJsWechatConfig();
jsWechatConfig.setAppId(WechatConfig.APP_ID);
jsWechatConfig.setTimestamp(DateTimeUtil.currentTime());
jsWechatConfig.setNoncestr(PayUtil.createNonceStr());
SortedMap map = new TreeMap();
map.put("jsapi_ticket", wechatAuthService.getTicket(wechatAuthService.findlastestToken()));
map.put("noncestr", jsWechatConfig.getNoncestr());
map.put("timestamp", jsWechatConfig.getTimestamp());
map.put("url", request.getRequestURL().toString());
String signature= SignatureUtil.createSha1Sign(map, null, SystemConfig.CHARACTER_ENCODING);
jsWechatConfig.setSignature(signature);
request.setAttribute("jsWechatConfig", jsWechatConfig);return "wechatauth/getLocation";
}
}
签名方法
/*** 通过Map中的所有元素参与签名
*
*@parammap 待参与签名的map集合
* @params apikey apikey中 如果为空则不参与签名,如果不为空则参与签名
*@return
*/
public static String createSha1Sign(SortedMapmap, String apiKey, String characterEncoding) {
String result=notSignParams(map, apiKey);
MessageDigest md= null;try{
md= MessageDigest.getInstance("SHA-1");byte[] digest =md.digest(result.getBytes());
result=byteToStr(digest);
}catch(NoSuchAlgorithmException e) {
e.printStackTrace();
}returnresult;
}
其他的签名方法点击查看
三、通过ready接口处理成功验证
以上执行完成,进入的完整的页面
获取地理位置地址: