1、微信JS-SDK參數配置及查找javascript
JS安全域名配置(查找:微信公衆號裏-公衆號設置-功能設置頁)前端
注:一、安全域名外網必須能夠訪問的到 java
二、域名不能有下劃線 web
三、要將(MP_verify_ZTbWVRm4MwKyq8mw.txt)次文件放到項目根目錄下,也就是上面的域名+次文件名稱外網能夠訪問的到。ajax
AppID、AppSecret及IP白名單設置。(微信公衆號裏-開發者中心-基本設置)spring
注:一、AppSecret獲取到必定必定必定要找個地方記下來,否則下一次還要從新獲取這樣會影響其餘已開發項目的使用。json
二、IP名單須要配置部署服務器IP。api
2、前端代碼
首先要引入微信提供的js庫安全
<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
經過config接口進行權限認證-error接口進行處理失敗認證-wx.scanQRCode({})掃一掃接口調用;服務器
注:一、config接口參數,這裏是經過ajax方式從後臺獲取,後面代碼會粘出來。
二、debug在調試階段值設置爲true。
<script type="text/javascript"> var timestamp = ""; var nonceStr = ""; var signature = ""; $.ajax({ url:"${pageContext.request.contextPath}/web/wxConfig/getWxConfig", data:{}, type:"POST", dataType:"json", async:false, cache:false, success:function(data){ timestamp = data.wxConfig.timestamp; nonceStr = data.wxConfig.nonceStr; signature = data.wxConfig.signature; } }); wx.config({ debug: false, // 開啓調試模式,調用的全部api的返回值會在客戶端alert出來,若要查看傳入的參數,能夠在pc端打開,參數信息會經過log打出,僅在pc端時纔會打印。 appId: "xxxxxxxxxx", // 必填,公衆號的惟一標識 timestamp: timestamp, // 必填,生成簽名的時間戳 ${wxConfig.timestamp} nonceStr: nonceStr, // 必填,生成簽名的隨機串 ${wxConfig.nonceStr} signature: signature,// 必填,簽名,見附錄1 ${wxConfig.signature} jsApiList: ['scanQRCode'] // 必填,須要使用的JS接口列表,全部JS接口列表見附錄2 }); wx.error(function(res) { alert("出錯了:" + res.errMsg); }); $("#train_signStatus").click(function() { wx.scanQRCode({ needResult : 1, desc : 'scanQRCode desc', success : function(res) { var url = res.resultStr; var memberId = $.cookie('userId'); var trainingId=url.substr(url.indexOf("trainingId=")+11,32); var type = url.substr(url.indexOf("type=")+5,1); $.ajax({ type: "POST", url: "${pageContext.request.contextPath}/web/webTraining/signInByQRCode", data : { trainingId:trainingId, memberId:memberId, type:type }, dataType : "json", success : function(res) { var status = res.status; if(status=='3'){ alert('已簽到'); }else if(status=='5'){ alert('上課簽到班主任未開啓'); }else if(status=='999'){ alert('簽到成功'); } window.location.reload(); } }); } }); }); </script>
3、java後臺代碼。
下面代碼注意事項:
1:url必須和請求jsp的url相同(查看可經過在jsp頁面alert輸出window.locatiion.href)-----否側會驗證失敗
import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import com.sms.util.Sign; import com.sms.util.WxUtils; @Controller @RequestMapping("web/wxConfig") public class WebWxConfig { @RequestMapping(value="/getWxConfig",method=RequestMethod.POST) @ResponseBody public ModelMap getWxConfig(HttpServletRequest request,ModelMap map){ //http://localhost/WX/browser/member/membertrain.jsp String url = "http://"+WxUtils.APP_DOMAIN+ request.getContextPath()+"/browser/member/membertrain.jsp"; String ticket = WxUtils.getTicket(); Map<String, String> sign = Sign.sign(ticket, url); for (Map.Entry entry : sign.entrySet()) { System.out.println(entry.getKey() + "," + entry.getValue()); } map.put("wxConfig", sign); return map; } }
下面代碼注意事項:
一、AppID和appSecret經過(一)獲取
二、getTicket獲取票據的方法,票據是微信簽名時必須用到的(重點-重點-重點),基本微信全部的接口都是須要票據的。
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import net.sf.json.JSONObject; public class WxUtils { private static String APP_ID = "XXXXXX"; private static String AppSecret = "XXXXXXXXXXXX"; public static String APP_DOMAIN ="www.oacloudapp.cn"; public static String getTicket(){ String urlToken="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+APP_ID+"&secret="+AppSecret+""; String backToken = sendGet(urlToken,"utf-8",60000); System.out.println("token:"+backToken); String accessToken = (String) JSONObject.fromObject(backToken).get("access_token"); String url="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+accessToken+"&type=jsapi"; String backTicket = sendGet(url,"utf-8",60000); System.out.println("Ticket:"+backTicket); String ticket = (String) JSONObject.fromObject(backTicket).get("ticket"); return ticket; } /** * * @title getAccessToken * @Description 獲取訪問令牌 * @author sss * @Date 2018-5-18上午11:07:18 * @return */ public static String getAccessToken(){ String url="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+APP_ID+"&secret="+AppSecret+""; String backData = sendGet(url,"utf-8",10000); String accessToken = (String) JSONObject.fromObject(backData).get("access_token"); return accessToken; } /** * * @title sendGet * @Description * @author sss * @Date 2018-5-18上午11:15:33 * @param url * @param charset * @param timeout * @return */ public static String sendGet(String url, String charset, int timeout) { String result = ""; try { URL u = new URL(url); try { URLConnection conn = u.openConnection(); conn.connect(); conn.setConnectTimeout(timeout); BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), charset)); String line=""; while ((line = in.readLine()) != null) { result = result + line; } in.close(); } catch (IOException e) { return result; } } catch (MalformedURLException e) { return result; } return result; } }
如下代碼是微信提供的Demo 生成簽名時使用。
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; public class Sign { /*public static void main(String[] args) { String ticket = WxUtils.getTicket(); // 注意 URL 必定要動態獲取,不能 hardcode String url = "http://"+WxUtils.APP_DOMAIN+"/RAFFLE/gotoLetter"; Map<String, String> ret = sign(ticket, url); for (Map.Entry entry : ret.entrySet()) { System.out.println(entry.getKey() + ", " + entry.getValue()); } };*/ 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 string1; String signature = ""; //注意這裏參數名必須所有小寫,且必須有序 string1 = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce_str + "×tamp=" + timestamp + "&url=" + url; System.out.println(string1); try { MessageDigest crypt = MessageDigest.getInstance("SHA-1"); crypt.reset(); crypt.update(string1.getBytes("UTF-8")); signature = byteToHex(crypt.digest()); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } 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().replace("-", ""); } private static String create_timestamp() { return Long.toString(System.currentTimeMillis() / 1000); } }