引言

电脑端微信网页扫码授权登录有2种方式:
第一种:基于微信公众号,单独获取登录二维码扫码,然后扫码登录,程序控制跳转逻辑,例如CSDN
第二种:基于微信开放平台,跳转到微信二维码页面进行扫码登录,重定向到成功页面,例如有道笔记

本文则是实现第一种授权登录

前期准备

内网渗透=>生成本地指定端口映射的外网域名

链接:内网渗透工具natapp使用详解
域名生成之后修改yml文件配置

申请并配置微信测试公众号

01、链接:点击申请微信测试公众号,并扫码关注测试公众号
02、备份appID和appsecret,后面需要用
03、接口配置信息修改(注:此处会回调后台签名验证方法,配置时需启动后台

04、配置网页授权域名,用于获取微信用户信息

编写代码

Maven依赖:

        <dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.54</version></dependency><!-- https://mvnrepository.com/artifact/com.github.binarywang/weixin-java-mp --><dependency><groupId>com.github.binarywang</groupId><artifactId>weixin-java-mp</artifactId><version>4.1.0</version></dependency><!-- https://mvnrepository.com/artifact/com.github.binarywang/weixin-java-common --><dependency><groupId>com.github.binarywang</groupId><artifactId>weixin-java-common</artifactId><version>4.1.0</version></dependency>

yml文件:

spring:thymeleaf:cache: false
wx:appId: wxb7ca6048ec426f03appSecret: d29708209e6e4707431bbd8cd314396eserver: http://au3sic.natappfree.ccqrCodeUrl: https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKENtokenUrl: https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRETopenIdUrl: https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRETuserInfoUrl: https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

HTML:

<body style="text-align: center;margin-top: 100px;"><h1>微信扫码登录方式一</h1><button onclick="getQrCode()" style="width: 100px;height: 50px;">获取二维码</button><br><img src="" id="qrCodeImgId"  style="width: 300px;height: 300px;display: none">
<hr>
<h1>微信扫码登录方式二</h1>
<button onclick="toQrCode()" style="width: 100px;height: 50px;">获取二维码</button>
<script>//======================================微信扫码登录方式一=========================================================// 存储二维码标识,用于验证是否扫码成功var sceneStr;var t;// 获取登录二维码function getQrCode(){$.get('qrCodeFirstLogin/getQrCode',function (data) {console.log("=============getQrCode=======================");console.log(data);if(data.code == 200){sceneStr = data.data.sceneStr;$('#qrCodeImgId').attr('src',"https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket="+data.data.ticket);$('#qrCodeImgId').show();t = window.setInterval(getOpenId,3000);}else{alert(data.msg);}});}// 扫码成功,获取用户openId=>为获取用户信息做准备function getOpenId() {$.get("qrCodeFirstLogin/getOpenId",{"eventKey":sceneStr},function (data) {if(data.code == 200){console.log("========getOpenId==========");console.log(data.data);window.clearInterval(t);alert("登录成功openId:"+data.data.openId);/*** 1、第一次扫码登录进行账号绑定* 2、以后根据openId获取用户信息*/}});}
</script>
</body>

controller层:

    @Autowiredprivate WxConfig wxConfig;// 模拟数据库存储或者缓存存储Map<String, CodeLoginKey> loginMap = new ConcurrentHashMap<>(64);/***  获取登录二维码* @return*/@RequestMapping("/getQrCode")private Object getQrCode(){try {log.info("获取二维码ing。。。");// 获取token开发者String accessToken =getAccessToken();String getQrCodeUrl = wxConfig.getQrCodeUrl().replace("TOKEN", accessToken);// 这里生成一个带参数的二维码,参数是scene_strString sceneStr = CodeLoginUtil.getRandomString(8);String json="{\"expire_seconds\": 604800, \"action_name\": \"QR_STR_SCENE\"" +", \"action_info\": {\"scene\": {\"scene_str\": \""+sceneStr+"\"}}}";String result  = HttpClientUtil.doPostJson(getQrCodeUrl,json);JSONObject jsonObject = JSONObject.parseObject(result);jsonObject.put("sceneStr",sceneStr);return ResultJson.ok(jsonObject);} catch (Exception e) {e.printStackTrace();return ResultJson.failure(ResultCode.GENERATOR_FAILURE,e.getMessage());}}/***  获取accessToken* @return*/public String getAccessToken(){String accessToken = null;String getTokenUrl = wxConfig.getTokenUrl().replace("APPID", wxConfig.getAppId()).replace("SECRET", wxConfig.getAppSecret());String result = HttpClientUtil.doGet(getTokenUrl);JSONObject jsonObject = JSONObject.parseObject(result);accessToken = jsonObject.getString("access_token");return accessToken ;}/***  验证签名* @param request* @return* @throws Exception*/@RequestMapping("/checkSign")public String checkSign ( HttpServletRequest request) throws Exception {log.info("===========>checkSign");//获取微信请求参数String signature = request.getParameter ("signature");String timestamp = request.getParameter ("timestamp");String nonce = request.getParameter ("nonce");String echostr = request.getParameter ("echostr");//参数排序。 token 就要换成自己实际写的 tokenString [] params = new String [] {timestamp,nonce,"123456"} ;Arrays.sort (params) ;//拼接String paramstr = params[0] + params[1] + params[2] ;//加密//获取 shal 算法封装类MessageDigest Sha1Dtgest = MessageDigest.getInstance("SHA-1") ;//进行加密byte [] digestResult = Sha1Dtgest.digest(paramstr.getBytes ("UTF-8"));//拿到加密结果String mysignature = CodeLoginUtil.bytes2HexString(digestResult);mysignature=mysignature.toLowerCase(Locale.ROOT);//是否正确boolean signsuccess = mysignature.equals(signature);//逻辑处理if (signsuccess && echostr!=null) {//peizhi  tokenreturn echostr  ;//不正确就直接返回失败提示.}else{JSONObject jsonObject = callback(request);return jsonObject.toJSONString();}}/***  回调方法* @param request* @return* @throws Exception*/public JSONObject callback(HttpServletRequest request) throws Exception{log.info("===========>callback");//request中有相应的信息,进行解析WxMpXmlMessage message= WxMpXmlMessage.fromXml(request.getInputStream());//获取消息流,并解析xmlString messageType=message.getMsgType();                                //消息类型String messageEvent=message.getEvent();                                  //消息事件// openidString fromUser=message.getFromUser();                                  //发送者帐号String touser=message.getToUser();                                      //开发者微信号String text=message.getContent();                                      //文本消息  文本内容// 生成二维码时穿过的特殊参数String eventKey=message.getEventKey();                                 //二维码参数String uuid="";                                                           //从二维码参数中获取uuid通过该uuid可通过websocket前端传数据String userid="";//if判断,判断查询JSONObject jsonObject = new JSONObject();jsonObject.put("code","200");if(messageType.equals("event")){jsonObject = null;//先根据openid从数据库查询  => 从自己数据库中查取用户信息 => jsonObjectif(messageEvent.equals("SCAN")){//扫描二维码//return "欢迎回来";}if(messageEvent.equals("subscribe")){//关注//return "谢谢您的关注";}//没有该用户if(jsonObject==null){//从微信上中拉取用户信息String url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" +getAccessToken() +"&openid=" + fromUser +"&lang=zh_CN";String result = HttpClientUtil.doGet(url);jsonObject = JSONObject.parseObject(result);/*** 用户信息处理....*/}// 扫码成功,存入缓存loginMap.put(eventKey,new CodeLoginKey(eventKey,fromUser));return jsonObject;}return jsonObject;//log.info("消息类型:{},消息事件:{},发送者账号:{},接收者微信:{},文本消息:{},二维码参数:{}",messageType,messageEvent,fromUser,touser,text,eventKey);}/***  根据二维码标识获取用户openId=>获取用户信息* @param eventKey* @return*/@RequestMapping("getOpenId")public ResultJson getOpenId(String eventKey){if(loginMap.get(eventKey) == null){return ResultJson.failure(ResultCode.OPERATE_ERROR,"未扫码成功!") ;}CodeLoginKey codeLoginKey = loginMap.get(eventKey);loginMap.remove(eventKey);return ResultJson.ok(codeLoginKey);}
}

除此之外,还有以下几个文件

由于篇幅有限,我就不放上去了。文章末尾会奉上源码作为参考。

结果展示


注:
1、测试是在浏览器中进行,输入的网址是:localhost:8080
2、第二张结果图只有在隧道运行状态正常时扫码才会出来,离线状态则无反应

本人的另一篇关于微信开发的博客:
Spring boot 项目(十三)——实现微信公众号授权登录获取用户信息

附:源码

电脑网页微信扫码自动授权

Spring boot 项目(十二)——实现电脑网页微信扫码自动授权相关推荐

  1. Spring Boot(十二)集成spring-boot-starter-mail发送邮件

    项目GitHub地址 : https://github.com/FrameReserve/TrainingBoot Spring Boot(十二)集成spring-boot-starter-mail发 ...

  2. 微信开放平台开发——网页微信扫码登录(OAuth2.0)

    1.OAuth2.0 OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用. 允许用户提供 ...

  3. Spring boot(十二):Spring boot 如何测试、打包、部署

    博文引用:springboot(十二):springboot如何测试打包部署 开发阶段 单元测试 Spring boot对单元测试的支持已经很完善了. 1 在pom包中添加Spring-boot-st ...

  4. Spring Boot(十二)单元测试JUnit

    一.介绍 JUnit是一款优秀的开源Java单元测试框架,也是目前使用率最高最流行的测试框架,开发工具Eclipse和IDEA对JUnit都有很好的支持,JUnit主要用于白盒测试和回归测试. 白盒测 ...

  5. 基于Spring Boot实现电脑端网页微信扫码授权登录方式一(附带完整源码)

    简介 电脑端微信网页扫码授权登录有2种方式: 第一种:基于微信公众号,单独获取登录二维码扫码,然后扫码登录,程序控制跳转逻辑,例如CSDN: 第二种:基于微信开放平台,跳转到微信二维码页面进行扫码登录 ...

  6. Java SpringMVC实现PC端网页微信扫码支付完整版

    一:前期微信支付扫盲知识 前提条件是已经有申请了微信支付功能的公众号,然后我们需要得到公众号APPID和微信商户号,这个分别在微信公众号和微信支付商家平台上面可以发现.其实在你申请成功支付功能之后,微 ...

  7. java web电脑网站微信扫码支付(Servlet+JSP)

    上篇文章写到了app开发中的微信支付和支付宝支付连接:https://blog.csdn.net/qq_35318713/article/details/92832397, 这次再把电脑网站扫码支付的 ...

  8. Spring boot 项目(二十六)——集成elasticsearch实现简单的书籍搜索

    前期准备 本地安装好es:安装教程 项目结构 代码编写 1.pom文件 <dependencies><!--springboot通用--><dependency>& ...

  9. Spring boot 项目(二十三)——用 Netty+Websocket实现聊天室

    Netty的介绍 Netty 是基于 Java NIO 的异步事件驱动的网络应用框架,使用 Netty 可以快速开发网络应用,Netty 提供了高层次的抽象来简化 TCP 和 UDP 服务器的编程,但 ...

最新文章

  1. gdb调试caffe工程
  2. 技术干货 | iOS 高阶容器详解
  3. 网易云信三周年:我们只做第一
  4. 1810: Huffuman树(vector模拟)
  5. 创新创业计划书_创践——大学生创新创业实务 ——如何撰写一份优秀的商业计划书...
  6. C++使用Windows API CreateMutex函数多线程编程
  7. 推荐美加版S3好用的两个ROM
  8. 浅析python类继承(一)
  9. 深入了解jquery中的ajax方法参数
  10. win764位和32位有什么区别_32位、64位它们是什么关系?它们又有什么区别?
  11. 生儿子的绝妙方法汇总,对程序猿特管用!!!
  12. 解决计算机系统问题开发的软件是,为解决计算机系统问题而开发的软件是。
  13. VS2005进行WORD文档开发
  14. ios版qq聊天记录的导出
  15. 深度学习笔试、面试题 二
  16. HTML在线转换JS
  17. fifa一直连接服务器,FIFA足球世界服务器连接掉线原因及解决方法
  18. 自建speedtest测速服务器教程,Linux/Windows/群晖
  19. 2063:【例1.4】牛吃牧草
  20. easyExcel的一些操作

热门文章

  1. 服务器2颗cpu的性能,DIY从入门到放弃:两颗CPU性能更强吗?
  2. mysql中端口的概念_端口的概念,端口的分类
  3. 互联网众筹系统开发-一站式搭建众筹项目建设
  4. java jar 最大内存大小_Java运行Jar包内存配置的操作
  5. 【Codevs1422】【网络流】河城荷取
  6. 计算机卡住了怎样恢复,电脑死机按什么键恢复
  7. 如何在笔试的时候绕开切屏提示
  8. hive 转拼音udf_自定义UDF函数:将汉字转换成拼音
  9. Scrapy 爬取今日头条街拍图片
  10. SylixOS设备驱动