微信平臺掃碼登陸時,由於開放平臺的openid與原系統不一致,因此使用了原公衆平臺二維碼掃碼後獲取用戶openid,繼而轉連接形式.javascript
油膩膩的大豬蹄進行測試
oysIt005E1TDKTKIdc8TmR6VTViA < 使用開放平臺的登陸二維碼掃碼獲取的openid html
o4mIl1jXCq4b2MkQ0tTZTzKzl2XY < 微信平臺獲取的openid前端
o4mIl1jXCq4b2MkQ0tTZTzKzl2XY < 掃碼臨時二維碼獲取的openidjava
大體流程:jquery
用戶點擊微信登陸->跳轉到該請求 wechat/wechatLoginweb
請求到該控制層ajax
package com.baigehuidi.demo.controller; import com.baigehuidi.demo.loader.WeixinInsLoader; import com.baigehuidi.demo.weixin4j.WeixinException; import com.baigehuidi.demo.weixin4j.model.qrcode.Qrcode; import com.baigehuidi.demo.weixin4j.model.qrcode.QrcodeType; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import java.util.Date; /** * 生成帶參二維碼 */ @Controller public class WeixinQrcodeController { //該方法爲用戶點擊微信登陸後請求的地址(第一步) @RequestMapping("/wechat/wechatLogin") public String wechatLogin(Model model) throws WeixinException { //場景字符串使用baige+時間 String scene_str = "baige"+new Date().getTime(); //字符串場景臨時二維碼 Qrcode qrcode = WeixinInsLoader.getWeixinInstance().qrcode().create(QrcodeType.QR_STR_SCENE,scene_str,600); String ticket = qrcode.getTicket(); String qrcodeUrl = null; if(ticket!=null){ qrcodeUrl = WeixinInsLoader.getWeixinInstance().qrcode().showQrcode(ticket);//方法中已經進行了encode } model.addAttribute("qrcodeUrl",qrcodeUrl); model.addAttribute("scene_str",scene_str); //return ModelAndView(qrcode展現頁面路徑,modelMap); //跳轉到二維碼展現頁面 (參數爲字母+時間戳) return "/wechat/qrcode"; } }
其中上面方法中執行了建立臨時二維碼的官方的api接口請求連接 create() 方法建立了二維碼spring
獲取ticket以後展現二維碼,獲取二維碼展現url showQrcode就是幹這個的.數據庫
以後將展現二維碼的路徑放到model裏,返回頁面到wechat/qrcodejson
wechat/qrcode
截取展現jsp的控制器中展現qrcode的:
/** * 掃碼登陸 臨時帶參二維碼版 qrcode二維碼展現頁面 * @return */ @RequestMapping("/wechat/qrcode") public String wqrcode(){ return "/wechat/qrcode"; }
展現的就是qrcode.jsp
<%-- 微信掃碼登陸 openid版本 --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>微信掃碼,關注並登陸</title> <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon"/> <style>a { outline: 0 } h1, h2, h3, h4, h5, h6, p { margin: 0; font-weight: 400 } a img, fieldset { border: 0 } body { font-family: "Microsoft Yahei"; color: #fff; background: 0 0 } .impowerBox { display: inline-block; vertical-align: middle; line-height: 1.6; position: relative; width: 100%; z-index: 1; text-align: center } .impowerBox .title { text-align: center; font-size: 20px } .impowerBox .qrcode { width: 280px; height: 280px; margin-top: 15px; border: 1px solid #E2E2E2 } .impowerBox .info { width: 280px; margin: 0 auto } .impowerBox .status { padding: 7px 14px; text-align: left } .impowerBox .status.normal { margin-top: 15px; background-color: #232323; border-radius: 100px; -moz-border-radius: 100px; -webkit-border-radius: 100px; box-shadow: inset 0 5px 10px -5px #191919, 0 1px 0 0 #444; -moz-box-shadow: inset 0 5px 10px -5px #191919, 0 1px 0 0 #444; -webkit-box-shadow: inset 0 5px 10px -5px #191919, 0 1px 0 0 #444 } .impowerBox .status.status_browser { text-align: center } .impowerBox .status p { font-size: 13px }</style> <script src="http://www.jq22.com/jquery/jquery-3.3.1.js"></script> </head> <body style="background-color: rgb(51, 51, 51); padding: 50px;"> <div class="main impowerBox"> <div class="loginPanel normalPanel"> <div class="title">微信登陸</div> <div class="waiting panelContent"> <div class="wrp_code"> <img class="qrcode lightBorder" src="${qrcodeUrl}"/> </div> <div class="info"> <div class="status status_browser js_status normal" id="wx_default_tip"> <p>請使用微信掃描二維碼登陸</p> <p>白鴿惠遞</p> </div> </div> </div> </div> </div> <script type="text/javascript"> $(document).ready(function () { setInterval("wechatCheckLogin()", 2000); }); function wechatCheckLogin() { $.post("/wechat/checkLogin", {scene_str: "${scene_str}"}, function (data) { console.log("請求/wechat/checkLogin方法中..."); //數據1, 成功獲取用戶信息 if (data.code===1) { window.location.href="http://baige.free.idcfengye.com/wechat/callback"; } else if(data.code===0) { //雖然有用戶openid,可是沒法獲取用戶信息,多是用戶取消了關注 //須要跳轉到從新掃碼生成界面 window.location.href="http://baige.free.idcfengye.com/wechat/wechatLogin"; }else if(data.code===-1){ //若是場景字符串爲空 -1 檢查場景字符串時間戳生成是否正確 window.location.href="http://baige.free.idcfengye.com/error"; }else if(data.code===-2){ //檢查openid爲何沒正確傳入 window.location.href="http://baige.free.idcfengye.com/error"; }else if(data.code===-3){ //-3 //二者都爲空,系統掛了嗎 window.location.href="http://baige.free.idcfengye.com/error"; } }, "JSON"); } </script> </body> </html>
上面jsp中對請求進行輪詢: wechat/checkLogin
下面是WeixinConnectionController中的請求到的方法:
/** * TODO 若是數據庫要進行更改,能夠根據當時生成的scene_str查詢用戶openid或具體信息 * 該方法爲 * @param scene_str * @return */ @ResponseBody @RequestMapping("/wechat/checkLogin") public Map wechatCheckLogin(String scene_str,HttpSession session) throws WeixinException { System.err.println("scene_str : " + scene_str); String toUserName = null;//用戶openid if (xmlObj != null) { toUserName = xmlObj.getToUserName(); System.out.println("toUserName:" + toUserName); } //其中scene_str爲場景字符串,使用了baige+時間戳 而toUserName則是掃碼用戶的openid if (scene_str != null && scene_str != "" && toUserName != null && toUserName != "") { System.err.println("wechatCheckLogin(String scene_str)->WeixinInsLoader.getWeixinInstance().getToken().getAccess_token()::::::"+WeixinInsLoader.getWeixinInstance().getToken().getAccess_token()); User user = WeixinInsLoader.getWeixinInstance().user().info(toUserName); System.out.println("user:"+user); Map map = new HashMap(); if(user!=null){ //成功獲取用戶狀態碼 // model.addAttribute(user); session.setAttribute("nickname",user.getNickname()); map.put("code",1); // map.put("user",user); return map; }else if(user==null && toUserName!=null && toUserName !=""){ //雖然有用戶openid,可是沒法獲取用戶信息,多是用戶取消了關注 //須要跳轉到從新掃碼生成界面 map.put("code",0); return map; } else if(scene_str == null && scene_str == ""){ //若是場景字符串爲空 -1 檢查場景字符串時間戳生成是否正確 map.put("code",-1); return map; }else if(toUserName == null && toUserName == ""){ //檢查openid爲何沒正確傳入 map.put("code",-2); return map; }else{ //二者都爲空,系統掛了嗎 map.put("code",-3); return map; } } return null; }
該方法寫在上面的Controller中雖有不太合適之嫌,但爲了趕着完工,如今先放到這裏,後期改善.
上面方法return map後,前端的qrcode.jsp頁面接收返回值,若是用戶已經掃碼,則能夠進行跳轉回調頁面.
這裏到回調wechat/callback頁面是由於若是僅僅獲取微信用戶信息,其實已經能夠獲取了:
經過上面的
User user = WeixinInsLoader.getWeixinInstance().user().info(toUserName);
該信息就是用戶的微信資料信息.
可是除了這個信息,網站只是經過微信進行登陸,其它的網站上的信息,帳戶,訂單等是對應該用戶的openid 或是openid同時的自增主鍵.
因此進入回調頁面是要獲取用戶的更詳盡的其它信息.
wechat/callback.jsp :
<%-- 缺乏樣式 (正在跳轉) --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>正在跳轉...</title> <script src="http://www.jq22.com/jquery/jquery-3.3.1.js"></script> </head> <body> <p>該頁面爲回調頁面,文本內容可爲空.</p> 歡迎您,<%=session.getAttribute("nickname")%>. 正在跳轉... <script> $.ajax({ // url: "/user/getOpenSnsUserInfoByCode", url: "/wechat/callbackAndGetUserInfo", // data: "${user.openid}", contentType: "application/json", dataType: "json", method: "POST", success: function (data) { if(data===1){ //right code -> to index window.location.href="http://baige.free.idcfengye.com"; }else{ //wrong code -> show error page window.location.href="http://baige.free.idcfengye.com/error"; } } }); </script> </body> </html>
wechat/callbackAndGetUserInfo:
/** * 將用戶信息放入session * * @param * @return * @throws WeixinException */ @ResponseBody @RequestMapping(value = "/wechat/callbackAndGetUserInfo", method = RequestMethod.POST) public Integer callBackAndGetUserInfo(HttpSession session) throws WeixinException { System.out.println("callBackAndGetUserInfo method"); String access_token = WeixinInsLoader.getWeixinInstance().getToken().getAccess_token(); System.err.println("Connection:Access_token:" + access_token); SnsUser snsUser = null; String openid = xmlObj.getToUserName(); System.out.println("openid:" + openid); User user = null; if (openid != null && openid != "") { //查詢該openid下的其它表數據,如帳戶表等,放入一個實體傳回到首頁 //這裏先只展現用戶信息 user = WeixinInsLoader.getWeixinInstance().user().info(openid); session.setAttribute("user",user); } //存數據庫 if (user != null) { return 1; } else { return 0; } }
這裏還有一些邏輯沒作,好比用戶以前關注過微信平臺,再返回來關注時,雖然用戶的openid仍是相同的,可是給出提示
應該是: 歡迎回來.
而第一次關注的則是 : 歡迎關注...並給出新手提示.
這裏還有一篇文章:
微信公衆號與微信開放平臺的openid不一致怎麼破解?unionID爲你解圍
簡單記錄下整個流程
最後補一個index.jsp
<%@ page import="com.baigehuidi.demo.weixin4j.model.user.User" %> <%@ page import="com.baigehuidi.demo.weixin4j.model.sns.SnsUser" %><%-- 測試首頁 將登陸作爲單獨的頁面 (也能夠在該頁面中進行彈出[或iframe形式或遮罩窗體形式]) TODO 每頁(包括子頁面)都應有登陸或者展現用戶暱稱的頭部bar 該頁面爲PC端. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>微信掃碼登陸</title> <script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.3.1.min.js"></script> <style> .link{display: none;} .show{display: block;} </style> </head> <body> TODO : index.jsp 該頁面也爲最終用戶登陸後的頁面,登陸後,再也不展現登陸集,而展現用戶名 <br> <p id="nickname"></p> 用戶登陸後設定session時間 <br> <a href="login">登陸集</a> <br> <a href="/menuCreate">自定義菜單</a> <br> <a href="/wxpay/notify">支付測試</a> <br> 測試號二維碼<br> <img src="img/0.jpg" style="height:300px;width:300px"> ${snsUser.nickname} <%if(session.getAttribute("user")!=null){%> <%User user = (User)session.getAttribute("user");%> <%=user.getNickname()%> <%}%> <%--<%if(session.getAttribute("SnsUser")!=null){%>--%> <%--<%SnsUser snsUser = (SnsUser)session.getAttribute("SnsUser");%>--%> <%--<%=snsUser.getNickname()%>--%> <%--<%}%>--%> <a href="" class="link a2 show">不是微信端</a> <a href="" class="link a1">微信端</a> <p>該頁面經過斷定是不是微信內置瀏覽器,執行/非執行網頁受權獲取用戶信息.</p> <script> function isWeiXin() { var ua = window.navigator.userAgent.toLowerCase(); console.log(ua);//mozilla/5.0 (iphone; cpu iphone os 9_1 like mac os x) applewebkit/601.1.46 (khtml, like gecko)version/9.0 mobile/13b143 safari/601.1 if (ua.match(/MicroMessenger/i) == 'micromessenger') { return true; } else { return false; } } if(isWeiXin()){ console.log(" 是來自微信內置瀏覽器"); $(".a1").addClass("show"); $(".a2").removeClass("show"); //是微信內置瀏覽器執行經過code獲取用戶信息 getSnsUserInfoByCode(); function getSnsUserInfoByCode(){ alert("getSnsUserInfoByCode in method"); //下面頁面爲手機端頁面獲取 $.ajax({ url: "/user/getSnsUserInfoByCode", // url: "/callBackLogin", data: "<%=request.getParameter("code")%>", contentType: "application/json", dataType: "json", method: "POST", success: function (data) { alert(JSON.stringify(data)); var nickname = data.SnsUser.nickname; $("#nickname").html(nickname+"同窗"); alert("你好啊,"+data.SnsUser.nickname+"同窗,很久不見你瘦了一大圈."); //將數據反填到html或jsp頁面上 } }); } } else{ console.log("不是來自微信內置瀏覽器"); $(".a2").addClass("show"); $(".a1").removeClass("show"); } </script> </body> </html>