码迷,mamicode.com
首页 > 微信 > 详细

[微信开发] - 使用普通扫码登录获取用户信息,非开放平台版本

时间:2018-12-16 14:44:17      阅读:363      评论:0      收藏:0      [点我收藏+]

标签:return   扫描二维码   ajax   enter   blank   内容   二维码扫码   微信平台   实体   

微信平台扫码登录时,因为开放平台的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) 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() 方法创建了二维码

获取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还是相同的,但是给出提示

应该是: 欢迎回来.

而第一次关注的则是 : 欢迎关注...并给出新手提示.

 

这里还有一篇文章:

微信公众号与微信开放平台的openid不一致怎么破解?unionID为你解围

[微信开发] - 使用普通扫码登录获取用户信息,非开放平台版本

标签:return   扫描二维码   ajax   enter   blank   内容   二维码扫码   微信平台   实体   

原文地址:https://www.cnblogs.com/ukzq/p/10126213.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!