本部分需要用到微信的js-sdk,微信js-sdk是微信公眾平臺面向網頁開發者提供的基于微信內的網頁開發工具包。
通過使用微信js-sdk,網頁開發者可借助微信高效地使用拍照、選圖、語音、位置等手機系統的能力,同時可以直接使用微信分享、掃一掃、卡券、支付等微信特有的能力,為微信用戶提供更優質的網頁體驗。
一、js-sdk引入
1.先登錄微信公眾平臺進入“公眾號設置”的“功能設置”里填寫“js接口安全域名”,和網頁授權一樣只是個域名。
2.在需要調用js接口的頁面引入如下js文件之一
1
2
|
<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> |
二、通過config接口注入權限驗證配置
1
2
3
4
5
6
7
8
|
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、獲取臨時票據
封裝返回結果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
package com.phil.wechatauth.model.resp; import com.phil.common.result.resultstate; /** * jsapi_ticket是公眾號用于調用微信js接口的臨時票據 * @author phil * @date 2017年8月21日 * */ public class jsapiticket extends resultstate { /** * */ private static final long serialversionuid = -357009110782376503l; private string ticket; //jsapi_ticket private string expires_in; public string getticket() { return ticket; } public void setticket(string ticket) { this .ticket = ticket; } public string getexpires_in() { return expires_in; } public void setexpires_in(string expires_in) { this .expires_in = expires_in; } } |
獲取方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
/** * 獲取jsapi_ticket 調用微信js接口的臨時票據 * @return */ public string getticket(string accesstoken) { jsapiticket jsapiticket = null ; map<string,string> params = new treemap<string,string>(); 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 ){ return jsapiticket.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配置信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
package com.phil.wechatauth.model.resp; /** * js-sdk的頁面配置信息 * @author phil * @date 2017年8月22日 * */ public class jswechatconfig { private string appid; private long timestamp; private string noncestr; private string signature; 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; } } |
添加配置信息到頁面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
/** * */ package com.phil.wechatauth.controller; import java.util.sortedmap; import java.util.treemap; import javax.servlet.http.httpservletrequest; import org.springframework.beans.factory.annotation.autowired; import org.springframework.stereotype.controller; import org.springframework.web.bind.annotation.requestmapping; import com.phil.common.config.systemconfig; import com.phil.common.config.wechatconfig; import com.phil.common.util.datetimeutil; import com.phil.common.util.payutil; import com.phil.common.util.signatureutil; import com.phil.wechatauth.model.resp.jswechatconfig; import com.phil.wechatauth.service.wechatauthservice; /** * js-sdk * @author phil * @date 2017年8月21日 * */ @controller @requestmapping ( "/auth" ) public class wechatauthcontroller { @autowired private wechatauthservice wechatauthservice; /** * 獲取地理位置 * @param request * @return * @throws exception */ @requestmapping ( "/getlocation" ) public string getlocation(httpservletrequest request) throws exception{ jswechatconfig jswechatconfig = new jswechatconfig(); jswechatconfig.setappid(wechatconfig.app_id); jswechatconfig.settimestamp(datetimeutil.currenttime()); jswechatconfig.setnoncestr(payutil.createnoncestr()); sortedmap<object,object> map = new treemap<object,object>(); 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" ; } } |
簽名方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
/** * 通過map<sortedmap,object>中的所有元素參與簽名 * * @param map 待參與簽名的map集合 * @params apikey apikey中 如果為空則不參與簽名,如果不為空則參與簽名 * @return */ public static string createsha1sign(sortedmap<object, object> map, 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(); } return result; } |
其他的簽名方法
三、通過ready接口處理成功驗證
以上執行完成,進入的完整的頁面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
<%@ page language= "java" contenttype= "text/html; charset=utf-8" pageencoding= "utf-8" %> <!doctype html public "-//w3c//dtd html 4.01 transitional//en" "http://www.w3.org/tr/html4/loose.dtd" > <html> <head> <meta http-equiv= "content-type" content= "text/html; charset=utf-8" > <title>獲取地理位置</title> <!-- 微信 js-sdk --> <script src= "http://res.wx.qq.com/open/js/jweixin-1.2.0.js" ></script> <link rel= "stylesheet" href= "http://cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css" > <script src= "http://cdn.bootcss.com/jquery/1.11.3/jquery.min.js" ></script> </head> <body> <br> <div class = "container" > <div class = "form-group" > <label for = "firstname" class = "col-sm-2 control-label" >地址:</label> <div class = "col-sm-10" id= "item-ifo" > <input type= "text" value= "" class = "form-control" name= "location.address" id= "address" placeholder= "正在獲取地理位置" tabindex= "1" autocomplete= "off" /> <div class = "i-name ico" id= "i-name" ></div> </div> </div> </div> </body> <script type= "text/javascript" > wx.config({ debug: true , // 開啟調試模式,調用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數,可以在pc端打開,參數信息會通過log打出,僅在pc端時才會打印。 appid: '${jswechatconfig.appid}' , // 必填,公眾號的唯一標識 timestamp: '${jswechatconfig.timestamp}' , // 必填,生成簽名的時間戳 noncestr: '${jswechatconfig.noncestr}' , // 必填,生成簽名的隨機串 signature: '${jswechatconfig.signature}' , // 必填,簽名,見附錄1 jsapilist: [ 'checkjsapi' , 'openlocation' , 'getlocation' ] // 必填,需要使用的js接口列表,所有js接口列表見附錄2 }); wx.checkjsapi({ jsapilist: [ 'getlocation' ], // 需要檢測的js接口列表,所有js接口列表見附錄2, success: function(res) { if (res.checkresult.getlocation == false ) { alert( '你的微信版本太低,不支持微信js接口,請升級到最新的微信版本!' ); return ; } } }); var latitude; var longitude; var speed; var accuracy; wx.ready(function(){ // config信息驗證后會執行ready方法,所有接口調用都必須在config接口獲得結果之后,config是一個客戶端的異步操作,所以如果需要在頁面加載時就調用相關接口,則須把相關接口放在ready函數中調用來確保正確執行。對于用戶觸發時才調用的接口,則可以直接調用,不需要放在ready函數中。 wx.getlocation({ success : function(res) { latitude = res.latitude; // 緯度,浮點數,范圍為90 ~ -90 longitude = res.longitude; // 經度,浮點數,范圍為180 ~ -180。 speed = res.speed; // 速度,以米/每秒計 accuracy = res.accuracy; // 位置精度 alert(latitude); alert(accuracy); }, cancel : function(res) { alert( '未能獲取地理位置' ); } }); }); wx.error(function(res){ // config信息驗證失敗會執行error函數,如簽名過期導致驗證失敗,具體錯誤信息可以打開config的debug模式查看,也可以在返回的res參數中查看,對于spa可以在這里更新簽名。 alert( "驗證出錯" ); }); </script> </html> |
可以通過微信官方提供的微信web開發者工具調試。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:https://blog.csdn.net/phil_jing/article/details/77466371