微信扫描自定义二维码关注公众号并登录(一)PC端网站的设计与实现

业务需求

大确幸网站实现扫描二维码关注微信公众号,如果已经关注公众号就自动登陆网站并获取其微信昵称,头像等信息,如果用户未关注就等用户关注公众号后自动登陆网站

--如果用户已关注公众号,网站端直接自动登陆,如果没有关注,就等用户关注公众号之后网站端自动登陆

(目前已经完成了这个功能,示例网址:https://love.daquexing.com/  大确幸-新社交,新生活,一个聚合百万单身年青的社群。大确幸是一个有温度的社区,宗旨是帮更多适龄单身青年解决单身问题。)

做微信扫码登陆,生成二维码必须是微信公众号中绑定的域这个域名,网站生成不了二维码(网站与微信服务器不是同一个域名) ,而是调用微信系统的接口获取二维码,用户扫码后也是请求微信服务器 。

ok 以上内容参考引用出自:

《网站实现扫描二维码关注微信公众号,自动登陆网站并获取其信息 》

《方案优化:网站实现扫描二维码关注微信公众号,自动登陆网站并获取其信息》

网上还有一篇文章推荐:

《微信扫描自定义二维码关注公众号》

如果以上三篇你都看懂了, 下面就简单, 或者你都不用看了。


微信扫描自定义二维码关注公众号并登录(一)PC端网站的设计与实现_第1张图片

微信公众平台技术文档:

获取access_token

https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183

生成带参数的二维码

https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1443433542

前端页面实现相关js

https://love.daquexing.com/theme/default/js/modules/authc.js

前端获取二维码方法:

@RequestMapping(value ="/qrcode", method = RequestMethod.GET)public @ResponseBodyData getqrcode(@RequestParam(value ="f")Stringf) {Data data = Data.failure("操作失败");Map map =newHashMap<>();Stringtimestamp = System.currentTimeMillis() +"";if("m".equals(f)) {timestamp ="m"+ timestamp;}map.put("timestamp", timestamp);// 获取二维码链接Stringresult = HttpKit.get(env.getProperty("api.url.wx_get_qrcode") + timestamp);if(StringUtils.isNotEmpty(result)) {JSONObject res =JSON.parseObject(result);map.put("ticket", res.get("ticket").toString());}returnData.success(map);}

/** * 登录 * *@paramusername *@paramtimestamp *@return*/@RequestMapping(value ="/wechat", method = RequestMethod.POST)public@ResponseBodyDatawechatlogin(String username, String timestamp)throwsException{    Data data = Data.failure("操作失败");//重置序列化redisTemplate.setValueSerializer(newGenericJackson2JsonRedisSerializer());if(StringUtils.isBlank(username) || StringUtils.isBlank(timestamp)) {returndata;    }// 获取用户if(redisTemplate.opsForValue().get("wechat_"+ timestamp) ==null) {        data.setMessage("获取用户失败");returndata;    }//  其他登录逻辑。。。。。。。}

后台服务的websocket 实现packagecom.lotres.mp.controller;importnet.sf.json.JSONObject;importorg.springframework.stereotype.Component;importjavax.websocket.*;importjavax.websocket.server.PathParam;importjavax.websocket.server.ServerEndpoint;importjava.io.IOException;importjava.util.Hashtable;importjava.util.concurrent.ConcurrentHashMap;importjava.util.concurrent.ConcurrentMap;/** *@ServerEndpoint注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端, * 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端 */@Component@ServerEndpoint("/websocket/wechat/{timestamp}")publicclassWebSocketController{//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。privatestaticintonlineCount =0;//concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识//private static CopyOnWriteArraySet webSocketSet = new CopyOnWriteArraySet();privatestaticConcurrentMap webSocketMap =newConcurrentHashMap();//与某个客户端的连接会话,需要通过它来给客户端发送数据privateSession session;/**    * 连接建立成功调用的方法    *    *@paramsession 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据    */@OnOpenpublicvoidonOpen(@PathParam("timestamp")String timestamp, Session session){this.session = session;        webSocketMap.put(timestamp,this);//在线数加1System.out.println("唯一key为:"+ timestamp);    }/**

    * 连接关闭调用的方法

    */@OnClosepublicvoidonClose(@PathParam("timestamp")String timestamp){        webSocketMap.remove(timestamp);//从map中删除}/**    * 收到客户端消息后调用的方法    *    *@parammessage 客户端发送过来的消息    *@paramsession 可选的参数    */@OnMessagepublicvoidonMessage(String message, Session session){        System.out.println("来自客户端的消息:"+ message);        JSONObject jsonobject = JSONObject.fromObject(message);        Hashtable params = (Hashtable) JSONObject.toBean(jsonobject, Hashtable.class);//群发消息WebSocketController webSocketController = webSocketMap.get(params.get("equipmentType"));try{            webSocketController.sendMessage((String) params.get("nickname"));        }catch(IOException e) {            e.printStackTrace();        }    }/**    * 发生错误时调用    *    *@paramsession    *@paramerror    */@OnErrorpublicvoidonError(Session session, Throwable error){        System.out.println("发生错误");        error.printStackTrace();    }/**    * 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。    *    *@parammessage    *@throwsIOException    */publicvoidsendMessage(String message)throwsIOException{this.session.getBasicRemote().sendText(message);//this.session.getAsyncRemote().sendText(message);}}

公众号后台配置


微信扫描自定义二维码关注公众号并登录(一)PC端网站的设计与实现_第2张图片

后台服务程序参考

https://github.com/binarywang/weixin-java-mp-demo-springboot

!!!好了,微信扫码关注公众号登录基本就实现了。 本系统实现直接使用了websocket 机制, 没有使用js 轮询检测用户是否已经扫码关注的方法。 轮询方法实现就是当系统生成带参数二维码后,获取到了后台生成的timestamp参数,前端js就开始轮询(例如:每三秒请求一次)。

致谢: 前面参考的几篇文章作者。

顺便提一下,我们系统使用了开源 https://gitee.com/mtons/mblog.  在此表示感谢!

最后,希望本文对你有帮助,欢迎体验一下

https://love.daquexing.com/login

如果你还有其他疑问,可以加我微信咨询


微信扫描自定义二维码关注公众号并登录(一)PC端网站的设计与实现_第3张图片

预告:《微信扫描自定义二维码关注公众号并登录(二)移动端/微信端的设计与实现》

你可能感兴趣的:(微信扫描自定义二维码关注公众号并登录(一)PC端网站的设计与实现)