电脑端微信网页扫码授权登录有2种方式:
第一种:基于微信公众号,单独获取登录二维码扫码,然后扫码登录,程序控制跳转逻辑,例如CSDN
第二种:基于微信开放平台,跳转到微信二维码页面进行扫码登录,重定向到成功页面,例如有道笔记
本文则是实现第一种授权登录
前期准备 内网渗透=>生成本地指定端口映射的外网域名链接:内网渗透工具natapp使用详解
域名生成之后修改yml文件配置
01、链接:点击申请微信测试公众号,并扫码关注测试公众号
02、备份appID和appsecret,后面需要用
03、接口配置信息修改(注:此处会回调后台签名验证方法,配置时需启动后台)
04、配置网页授权域名,用于获取微信用户信息
Maven依赖:
org.apache.httpcomponents httpclientcom.alibaba fastjson1.2.54 com.github.binarywang weixin-java-mp4.1.0 com.github.binarywang weixin-java-common4.1.0
yml文件:
spring: thymeleaf: cache: false wx: appId: wxb7ca6048ec426f03 appSecret: d29708209e6e4707431bbd8cd314396e server: http://au3sic.natappfree.cc qrCodeUrl: https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN tokenUrl: https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRET openIdUrl: https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRET userInfoUrl: https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
HTML:
微信扫码登录方式一
微信扫码登录方式二
controller层:
@Autowired private WxConfig wxConfig; // 模拟数据库存储或者缓存存储 MaploginMap = new ConcurrentHashMap<>(64); @RequestMapping("/getQrCode") private Object getQrCode(){ try { log.info("获取二维码ing。。。"); // 获取token开发者 String accessToken =getAccessToken(); String getQrCodeUrl = wxConfig.getQrCodeUrl().replace("TOKEN", accessToken); // 这里生成一个带参数的二维码,参数是scene_str String 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()); } } 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 ; } @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 就要换成自己实际写的 token String [] 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 token return echostr ;//不正确就直接返回失败提示. }else{ JSONObject jsonObject = callback(request); return jsonObject.toJSONString(); } } public JSONObject callback(HttpServletRequest request) throws Exception{ log.info("===========>callback"); //request中有相应的信息,进行解析 WxMpXmlMessage message= WxMpXmlMessage.fromXml(request.getInputStream());//获取消息流,并解析xml String messageType=message.getMsgType(); //消息类型 String messageEvent=message.getEvent(); //消息事件 // openid String 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从数据库查询 => 从自己数据库中查取用户信息 => jsonObject if(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); } @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、第二张结果图只有在隧道运行状态正常时扫码才会出来,离线状态则无反应
电脑网页微信扫码自动授权
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)