600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > PC端微信扫码关注公众号并登录

PC端微信扫码关注公众号并登录

时间:2023-06-15 18:13:22

相关推荐

PC端微信扫码关注公众号并登录

碰到这样一个需求,PC端生成公众号二维码,用户用手机微信扫描,如果用户未关注公众号,则关注公众号后自动登录,如果用户已经关注过公众号,则直接登录。

前端Vue,后端Java实现

分2步来完成:

1.生成带参数的临时二维码

https://developers./doc/offiaccount/Account_Management/Generating_a_Parametric_QR_Code.html

2. 公众号后台服务监听扫码事件并获取用户信息

https://developers./doc/offiaccount/Message_Management/Receiving_event_pushes.html

https://developers./doc/offiaccount/User_Management/Get_users_basic_information_UnionID.html#UinonId

1.生成带参数的临时二维码

获取临时二维码的接口为微信官方提供的

https://api./cgi-bin/qrcode/create?access_token=TOKEN,注意为POST方式

@RequestMapping("/getQRCode")public Map<String,Object> getQRCode(HttpServletRequest request,String code) {Map<String,Object> map = new HashMap<String,Object>();String code_url = "https://api./cgi-bin/qrcode/create?access_token=TOKEN";try{//获取公众号的Token,自行实现,我是定任务获取,存到了数据库PcAccessToken token = accessTokenService.findPcToken("");code_url = code_url.replace("TOKEN", token.getAccessToken());String scene_id = (System.currentTimeMillis()+"").substring(0,10);JSONObject json = new JSONObject();json.put("expire_seconds", "36000");json.put("action_name", "QR_SCENE");JSONObject info = new JSONObject();JSONObject scen = new JSONObject();scen.put("scene_id", scene_id);info.put("scene", scen);json.put("action_info", info);String data = HttpUtil.requestPost(code_url, json.toString());JSONObject resp = JSONObject.fromObject(data);System.out.println("data=="+data);map.put("data", resp);map.put("scene_id", scene_id);map.put("succ", "1");} catch(Exception e){map.put("succ", "0");e.printStackTrace();}return map;}

请求微信接口返回的数据,url参数即为二维码地址,和scene_id一起返回给前端。

前端vue使用qrcodejs2组件,将url转为二维码图片,显示在相应位置。请求到二维码后,用sceneId查询扫码登录是否成功。

<div class="" id="qrcode" ref="qrcode"></div>import QRCode from 'qrcodejs2'import loginApi from '@/api/login';data(){return{url: '', //二维码地址sceneId:'',//二维码带的参数,用来判断是那个用户扫码的timer: null,//定时器}},created(){getLoginQRCode();},methods:{async getLoginQRCode(){this.url = '';window.clearInterval(this.timer);const res = await loginApi.getQRCode();console.log('44res',res)if(res.data.succ == '1'){this.url = res.data.data.url;this.sceneId = res.data.scene_id;console.log('sceneId',res.data.scene_id);this.timer = setInterval(this.getUserByScene, 1000);this.$nextTick(() => {this.getQrcode(this.url)})}},//根据 sceneId 轮询查询用户信息,判断用户是否登录成功async getUserByScene(){if(!this.sceneId) return;const res = await loginApi.getUserBySceneId({sceneId: this.sceneId});console.log('getUser', res);if(res.data.succ == '1' && res.data.user){this.user = res.data.user;window.clearInterval(this.timer);this.url = '';this.sceneId = '';//登录成功,处理登录成功逻辑this.$Message.success('登录成功')}},getQrcode (text) {this.$refs.qrcode.innerHTML = '' // 清除const qrcode = new QRCode('qrcode', {width: 160,height: 160,text: text, // 二维码地址colorDark: '#000',colorLight: '#fff'})return qrcode},}

2.公众号后台服务监听扫码事件并获取用户信息

这块要在微信公众平台配置服务地址信息

开发—基本配置

服务器配置信息提交的时候要验证 TOKEN, 验证通过才能提交。checkToken接口GET请求用来验证TOKEN,

import java.security.MessageDigest;//...@RequestMapping(value="/checkToken",method=RequestMethod.GET)public String checkToken(HttpServletRequest req, HttpServletResponse resp)throws IOException {req.setCharacterEncoding("UTF-8");resp.setCharacterEncoding("UTF-8");String message = "success";String signature = req.getParameter("signature");String timestamp = req.getParameter("timestamp");String nonce = req.getParameter("nonce");String echostr = req.getParameter("echostr");try {String[] arr = {"sjyx", timestamp, nonce};Arrays.sort(arr);StringBuilder content = new StringBuilder();for (int i = 0; i < arr.length; i++) {content.append(arr[i]);}//sha1Hex 加密MessageDigest md = null;String temp = null;md = MessageDigest.getInstance("SHA-1");byte[] digest = md.digest(content.toString().getBytes());temp = byteToStr(digest);if ((temp.toLowerCase()).equals(signature)){return echostr;}return null;} catch (Exception e) {e.printStackTrace();}return message;}private static String byteToStr(byte[] byteArray){String strDigest = "";for (int i = 0; i < byteArray.length; i++) {strDigest += byteToHexStr(byteArray[i]);}return strDigest;}private static String byteToHexStr(byte mByte){char[] Digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A','B', 'C', 'D', 'E', 'F' };char[] tempArr = new char[2];tempArr[0] = Digit[(mByte >>> 4)& 0X0F];tempArr[1] = Digit[mByte & 0X0F];String s = new String(tempArr);return s;}

checkToken接口POST请求用来监听扫码事件,并获取用户信息

@RequestMapping(value="/checkToken",method=RequestMethod.POST)public String responseEvent(HttpServletRequest req, HttpServletResponse resp) {String message = "success";try {//把微信返回的xml信息转义成mapMap<String, String> map = XmlUtil.xmlToMap(req);System.out.println("微信接收到的消息为:"+map.toString());String openId = map.get("FromUserName");//消息来源用户标识String toUserName = map.get("ToUserName");//消息目的用户标识String msgType = map.get("MsgType");//消息类型(event或者text)String EventKey = map.get("EventKey");//消息来源用户标识if(EventKey.contains("_")){ //scene_id首次关注会有前缀,去掉就和生成二维码时带的一致了EventKey = EventKey.split("_")[1];}String scene_Id = EventKey;String eventType = map.get("Event");//事件类型if("subscribe".equals(eventType) || "SCAN".equals(eventType) ){ //关注 or 浏览//获取缓存的最新的公众号 tokenPcAccessToken token = accessTokenService.findPcToken("");String USER_INFO_URL = "https://api./cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";USER_INFO_URL = USER_INFO_URL.replace("ACCESS_TOKEN", token.getAccessToken());USER_INFO_URL = USER_INFO_URL.replace("OPENID", openId);String info = HttpUtil.getRequest(USER_INFO_URL);System.out.println("----user-----"+info);JSONObject obj = JSONObject.fromObject(info);String unionid = obj.getString("unionid");String nickname = obj.getString("nickname");String headimgurl = obj.getString("headimgurl");String city = obj.getString("city");String province = obj.getString("province");String qr_scene = obj.getString("qr_scene");//获取到用户信息后处理登录逻辑,比如保存用户信息,用户表scene_id 字段,保存二维码的scend_id,供前端查询用户登录情况。}} catch (Exception e) {e.printStackTrace();}return message;}

xml转Map工具类

import java.io.IOException;import java.io.InputStream;import java.util.HashMap;import java.util.List;import java.util.Map;import javax.servlet.http.HttpServletRequest;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.Element;import org.dom4j.io.SAXReader;public class XmlUtil {/** xml转map*/public static Map<String, String> xmlToMap(HttpServletRequest request) throws IOException, DocumentException{HashMap<String, String> map = new HashMap<String,String>();SAXReader reader = new SAXReader();InputStream ins = request.getInputStream();Document doc = reader.read(ins);Element root = doc.getRootElement();@SuppressWarnings("unchecked")List<Element> list = (List<Element>)root.elements();for(Element e:list){map.put(e.getName(), e.getText());}ins.close();return map;}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。