JAVA微信扫码登录 您所在的位置:网站首页 java实现微信登陆 JAVA微信扫码登录

JAVA微信扫码登录

2024-01-17 17:04| 来源: 网络整理| 查看: 265

1、说明

本帖有两种微信扫码的方式。根据测试公众号进行测试,所以不用担心没有公众号。 因为涉及到微信回调,所以要走本地的话需要进行内网穿透,本贴不包含内网穿透教学,很简单,请自行百度。

2、测试号配置

测试号地址:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login 扫码登录后,进行配置。 在这里插入图片描述在这里插入图片描述 ![在这里插入图片描述](https://img-blog.csdnimg.cn/60452a52382c4871b0a379aadbcaaf9a.png

3、代码 3.1 依赖 com.github.binarywang weixin-java-mp 4.3.0 cn.hutool hutool-all 5.7.0 3.2 配置文件 #APPID wx.login.appid=wx9e******e7 #secret wx.login.appsecret=17bb2e***********ec0467 wx.login.token=weixin #回调地址(内网穿透地址) wx.login.server=http://elwin.*************.com #获取二维码 wx.login.qrCodeUrl: https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN #基础接口的token wx.login.tokenUrl: https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET #获取openId wx.login.openIdUrl: https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=APPSECRET&code=CODE&grant_type=authorization_code #获取用户 wx.login.userInfoUrl: https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN #通过ticket获取二维码 wx.login.showqrcode: https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET 3.3 公共类 @Component public class WxLoginConfig { @Value("${wx.login.appid}") private String appId; //公众号标识 @Value("${wx.login.appsecret}") private String appSecret; //公众号密码 @Value("${wx.login.server}") private String server; //服务器域名地址,用于微信服务器回调。 @Value("${wx.login.qrCodeUrl}") private String qrCodeUrl; //获取code接口 @Value("${wx.login.tokenUrl}") private String tokenUrl; //获取token接口 @Value("${wx.login.openIdUrl}") private String openIdUrl; //获取openid接口 @Value("${wx.login.userInfoUrl}") private String userInfoUrl; //获取用户信息接口 @Value("${wx.login.token}") private String token; @Value("${wx.login.showqrcode}") //通过ticket获取二维码 private String showQrCode; } 3.4 方式一

这种方式其实就是生一个二维码,二维码的内容是一个url。url的核心是REDIRECT_URL即回调地址。扫码之后,微信会根据REDIRECT_URL进行回调。

@Controller @RequestMapping("/wx/login") public class WxLoginController { @Autowired private WxLoginConfig wxLoginConfig; @Autowired private RestTemplate restTemplate; //生成二维码 @GetMapping(value = "/qrCode") public void getQrCode(@RequestParam(value = "isRememberMe",required = false,defaultValue = "1")String isRememberMe, @RequestParam(value = "sign") String sign, HttpServletRequest request, HttpServletResponse response) throws IOException { String url = wxLoginConfig.getQrCodeUrl().replace("APPID",wxLoginConfig.getAppId()) .replace("REDIRECT_URL",wxLoginConfig.getServer() + "/wx/login/callback") .replace("STATE","自定义传参"); //生成二维码的,扫描后跳转上面的REDIRECT_URL地址 QrCodeUtil.generate(url, 300, 300, "jpg", response.getOutputStream()); } //回调 @RequestMapping(value = "/callback") @ResponseBody public String pcCallback(String code, String state) throws Exception { String openId = getOpenId(code); System.out.println(openId); //获取微信用户信息 getUserInfo(openId); //业务处理... return "登录成功"; } /** * 获取openId * @param code * @return */ private String getOpenId(String code){ String url = wxLoginConfig.getOpenIdUrl().replace("APPID", wxLoginConfig.getAppId()) .replace("APPSECRET", wxLoginConfig.getAppSecret()).replace("CODE",code); ResponseEntity responseEntity = restTemplate.getForEntity(url, String.class); String body = responseEntity.getBody(); JSONObject object = JSONObject.parseObject(body); return object.getString("openid"); } /** * 获取用户信息 * @param openId * @return */ private JSONObject getUserInfo(String openId){ //从微信上中拉取用户信息 String url = wxLoginConfig.getUserInfoUrl().replace("ACCESS_TOKEN",getAccessToken()).replace("OPENID",openId); ResponseEntity forEntity = restTemplate.getForEntity(url, String.class); String result = forEntity.getBody(); JSONObject jsonObject = JSONObject.parseObject(result); return jsonObject; } } 3.5 方式二

先进行认证,提交 在这里插入图片描述

然后获取 access_token

拿到 ticket

生成二维码

扫码后,根据上图中token验证的接口地址进行回调

@Controller @RequestMapping("/wx/login") public class WxLoginController { @Autowired private WxLoginConfig wxLoginConfig; @Autowired private RestTemplate restTemplate; /** * pc点击微信登录,生成登录二维码 * @throws Exception */ @GetMapping(value = "/pcQrCode") @ResponseBody public void wxLoginPage(HttpServletRequest request, HttpServletResponse response) throws Exception { try { //获取token String accessToken =getAccessToken(); //获取 ticket String ticket = getTicket(accessToken); //获取二维码 String qrCodeUrl = wxLoginConfig.getShowQrCode().replace("TICKET",ticket); ResponseEntity forEntity = restTemplate.getForEntity(qrCodeUrl, byte[].class); byte[] body1 = forEntity.getBody(); response.getOutputStream().write(body1); } catch (Exception e) { e.printStackTrace(); } } /** * 获取accessToken * @return */ public String getAccessToken(){ //根据appid和appsecret获取access_token wxLoginConfig.getTokenUrl(); String url = wxLoginConfig.getTokenUrl().replace("APPID", wxLoginConfig.getAppId()).replace("APPSECRET", wxLoginConfig.getAppSecret()); HttpHeaders headers = new HttpHeaders(); ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.GET, new HttpEntity(null, headers), JSONObject.class); JSONObject object = responseEntity.getBody(); String accessToken = ""; accessToken = object.getString("access_token"); return accessToken ; } /** * 获取ticket * @param accessToken * @return */ public String getTicket(String accessToken){ //请求地址 String getQrCodeUrl = wxLoginConfig.getQrCodeUrl().replace("TOKEN", accessToken); HttpHeaders headers = new HttpHeaders(); //参数设置 Map map = new HashMap(); //二维码的过期时间,单位为秒,最大2592000(即30天)不填,则默认有效期为60秒。 map.put("expire_seconds", "604800"); //二维码类型,QR_SCENE为临时的整型参数值,QR_STR_SCENE为临时的字符串参数值,QR_LIMIT_SCENE为永久的整型参数值,QR_LIMIT_STR_SCENE为永久的字符串参数值 map.put("action_name", "QR_LIMIT_STR_SCENE"); Map innerThenMap = new HashMap(); //扫码回调时自定义要传输的数据 innerThenMap.put("scene_str","elwin123"); Map innerMap = new HashMap(); innerMap.put("scene",innerThenMap); //二维码详细信息 map.put("action_info", innerMap); // 组装请求体 HttpEntity sendMap = new HttpEntity(map, headers); ResponseEntity responseEntity = restTemplate.postForEntity(getQrCodeUrl, sendMap, String.class); String body = responseEntity.getBody(); JSONObject jsonObject = JSONObject.parseObject(body); String ticket = jsonObject.getString("ticket"); return ticket; } @RequestMapping("/checkSign") public String checkSign ( HttpServletRequest request) throws Exception { //获取微信请求参数 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, "weixin"}; 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 = bytes2HexString(digestResult); mysignature = mysignature.toLowerCase(Locale.ROOT); //是否正确 boolean signsuccess = mysignature.equals(signature); //逻辑处理 if (signsuccess && echostr != null) { //验证签名,接入服务器 return echostr; } else { //接入成功后,下次回调过来就可以进行正常业务处理 return callback(request); } } private String bytes2HexString(byte... bytes) { char[] hexChars = new char[bytes.length * 2]; char[] hexArray = "0123456789ABCDEF".toCharArray(); for (int j = 0; j //解析 WxMpXmlMessage message= WxMpXmlMessage.fromXml(request.getInputStream());//获取消息流,并解析xml String messageType=message.getMsgType(); //消息类型 String messageEvent=message.getEvent(); //消息事件 String openId =message.getFromUser(); //发送者帐号 String touser=message.getToUser(); //开发者微信号 String text=message.getContent(); //文本消息 文本内容 String eventKey=message.getEventKey(); //二维码参数 if(messageType.equals("event")){ //获取微信用户信息 JSONObject userInfo = this.getUserInfo(openId); //根据不同的回调事件处理各自的业务 switch (messageEvent){ case "SCAN": //扫码 System.out.println("扫码"); //业务处理... return "result"; case "subscribe": //关注公众号 System.out.println("关注公众号"); //业务处理... return "result"; case "unsubscribe": //取消关注公众号 System.out.println("取消关注公众号"); //业务处理... return "result"; } } return "111"; } /** * 获取用户信息 * @param openId * @return */ private JSONObject getUserInfo(String openId){ //从微信上中拉取用户信息 String url = wxLoginConfig.getUserInfoUrl().replace("ACCESS_TOKEN",getAccessToken()).replace("OPENID",openId); ResponseEntity forEntity = restTemplate.getForEntity(url, String.class); String result = forEntity.getBody(); JSONObject jsonObject = JSONObject.parseObject(result); return jsonObject; } } 4、参考地址: https://blog.csdn.net/m0_54881904/article/details/124400901https://blog.csdn.net/weixin_43890049/article/details/119463862#comments_22614248微信公众测试平台:微信公众测试平台获取Access token:获取Access token生成带参数的二维码:生成带参数的二维码 5、问题 5.1 {“errcode”:40125,“errmsg”:“invalid appsecret rid: 6368b9e5-0555a81b-3c7588c4”}

检查appid和appsecret是不是配置文件没写对

5.2 redirect_uri域名与后台配置不一致,错误码10003

在这里插入图片描述

回调地址没对



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有