如何获取微信开放平台的预授权码

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何获取微信开放平台的预授权码相关的知识,希望对你有一定的参考价值。

参考技术A 1、推送component_verify_ticket 出于安全考虑,在第三方平台创建审核通过后,微信服务器每隔10分钟会向第三方的消息接收地址推送一次component_verify_ticket,用于获取第三方平台接口调用凭据

2、获取第三方平台component_access_token 第三方平台通过自己的component_appid(即在微信开放平台管理中心的第三方平台详情页中的AppID和AppSecret)和component_appsecret,以及component_verify_ticket(每10分钟推送一次的安全ticket)来获取自己的接口调用凭据(component_access_token)

3、获取预授权码pre_auth_code 第三方平台通过自己的接口调用凭据(component_access_token)来获取用于授权流程准备的预授权码(pre_auth_code)

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

微信平台扫码登录时,因为开放平台的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为你解围

 

简单记录下整个流程

 

最后补一个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" %>
<微信开放平台获取授权公众号的流程

PHP开发,微信开放平台授权的问题

微信开放平台之获取用户信息的授权方式扩展

微信开放平台开发 移动应用微信登录

微信开发之分清公众平台和开放平台公众号全局凭证和网页授权凭证

android 微信开放平台,如何获取应用签名