[微信開發] - 使用普通掃碼登入獲取使用者資訊,非開放平臺版本
微信平臺掃碼登入時,因為開放平臺的openid與原系統不一致,所以使用了原公眾平臺二維碼掃碼後獲取使用者openid,繼而轉連結形式.
油膩膩的大豬蹄進行測試
oysIt005E1TDKTKIdc8TmR6VTViA < 使用開放平臺的登入二維碼掃碼獲取的openid
o4mIl1jXCq4b2MkQ0tTZTzKzl2XY < 微信平臺獲取的openid
o4mIl1jXCq4b2MkQ0tTZTzKzl2XY < 掃碼臨時二維碼獲取的openid
大致流程:
使用者點選微信登入->跳轉到該請求 wechat/wechatLogin
請求到該控制層
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) throwsWeixinException { //場景字串使用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() 方法建立了二維碼
獲取ticket之後展示二維碼,獲取二維碼展示url showQrcode就是幹這個的.
之後將展示二維碼的路徑放到model裡,返回頁面到wechat/qrcode
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還是相同的,但是給出提示
應該是: 歡迎回來.
而第一次關注的則是 : 歡迎關注...並給出新手提示.
這裡還有一篇文章: