[微信開發] - 使用普通掃碼登陸獲取用戶信息,非開放平臺版本

微信平臺掃碼登陸時,由於開放平臺的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>
相關文章
相關標籤/搜索