如何获取微信开放平台的预授权码
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" %> <微信开放平台获取授权公众号的流程