时间:2023-10-03 点击: 次 来源:网络 添加者:佚名 - 小 + 大
前言 最近需要做一些和微信相关的项目,第一个需求是用户访问进来后直接获取用户基本数据并存入数据库,实现用户的自动注册,以前没有接触过微信的开发,记录一下。 看了一天文档实现用户调用接口后获取到基本信息。 ===============================开始======================================= 首先去注册微信公众号测试号。 https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login 注册后扫码进去做一些配置。 首先看到的是这两个数据,开发者的两个凭证数据 往下翻看到一个二维码,手机扫描关注,这个是绑定为测试人员的,否则无法测试 再往下看到授权获取用户信息哪里进去 这里注意域名不要加http或者https,直接写例如www.baidu.com就好了。 没有域名的可以用内网穿透工具,我用的是natapp https://natapp.cn/,只是做测试选择购买免费的就好了,具体的使用百度一下吧,很简单,需要注意的就是设置端口的时候设置为80,因为微信这边要求必须是80。 运行natapp得到的Forwarding填进去就可以了,你也可以使用这个实现公网对本地服务的访问。 回到最上面这里也需要进行配置 URL是这边会像你自己的服务器发送一个验证信息,收到消息返回信息就可以,具体的我就不解释了。 Token是自己随便写的,与服务器设置的一致就好了。 所以可以开始代码的编写。 首先是实现接口的验证,分为工具类和一个Controller层 package com.sakura.wxdemo.utils; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /** * @Author: Sakura * @Description: 校验工具 * @Date: 2019/3/8 10:15 */ public class WxCheckoutUtil { // 与接口配置信息中的Token要一致 private static String token = "Sakura"; /** * 验证签名 */ public static boolean checkSignature(String signature, String timestamp, String nonce) { String[] arr = new String[] { token, timestamp, nonce }; // 将token、timestamp、nonce三个参数进行字典序排序 // Arrays.sort(arr); sort(arr); StringBuilder content = new StringBuilder(); for (int i = 0; i < arr.length; i++) { content.append(arr[i]); } MessageDigest md = null; String tmpStr = null; try { md = MessageDigest.getInstance("SHA-1"); // 将三个参数字符串拼接成一个字符串进行sha1加密 byte[] digest = md.digest(content.toString().getBytes()); tmpStr = byteToStr(digest); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } content = null; // 将sha1加密后的字符串可与signature对比,标识该请求来源于微信 return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false; } /** * 将字节数组转换为十六进制字符串 */ 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; } public static void sort(String a[]) { for (int i = 0; i < a.length - 1; i++) { for (int j = i + 1; j < a.length; j++) { if (a[j].compareTo(a[i]) < 0) { String temp = a[i]; a[i] = a[j]; a[j] = temp; } } } } } package com.sakura.wxdemo.controller; import com.sakura.wxdemo.utils.WxCheckoutUtil; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; /** * @Author: Sakura * @Description: 校验接口 * @Date: 2019/3/8 10:16 */ @RestController public class CheckoutController { /** * 微信消息接收和token验证 * * @param request * @param response */ @RequestMapping("/checkout") public void hello(HttpServletRequest request, HttpServletResponse response) { boolean isGet = request.getMethod().toLowerCase().equals("get"); PrintWriter print; if (isGet) { // 微信加密签名 String signature = request.getParameter("signature"); // 时间戳 String timestamp = request.getParameter("timestamp"); // 随机数 String nonce = request.getParameter("nonce"); // 随机字符串 String echostr = request.getParameter("echostr"); // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败 if (signature != null && WxCheckoutUtil.checkSignature(signature, timestamp, nonce)) { try { print = response.getWriter(); print.write(echostr); print.flush(); } catch (IOException e) { e.printStackTrace(); } } } } } 这边完成后启动你的服务,输入Token和URL确定后会进行校验,成功后就可以用了。 接着开始获取用户的数据 提供一个工具类和Controller package com.sakura.wxdemo.utils; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.util.EntityUtils; import java.io.IOException; /** * @Author: Sakura * @Description: * @Date: 2019/3/7 14:22 */ public class WxAuthUtil { public static final String APP_ID = "wx720735d82cf88e8d"; public static final String APP_SECRET = "17c1197f8d58babe9eba696a2d59cab1"; public static JSONObject doGetJson(String url) throws IOException { JSONObject jsonObject = null; DefaultHttpClient client = new DefaultHttpClient(); final HttpGet httpGet = new HttpGet(url); HttpResponse response = client.execute(httpGet); HttpEntity entity = response.getEntity(); if (entity != null) { // 返回结果转化为JSON对象 final String result = EntityUtils.toString(entity, "UTF-8"); jsonObject = JSON.parseObject(result); } return jsonObject; } } package com.sakura.wxdemo.controller; import com.alibaba.fastjson.JSONObject; import com.sakura.wxdemo.utils.WxAuthUtil; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.net.URLEncoder; /** * @Author: Sakura * @Description: * @Date: 2019/3/7 14:18 */ @RestController public class LoginController { /** * @Description: 微信公众号登录授权 * @auther: Sakura * @date: 2019/3/8 9:46 * @param: [request, response] * @return: java.lang.String */ @GetMapping(value = "/login") public void login(HttpServletRequest request, HttpServletResponse response) throws IOException { // 回调地址,该域名需要公众号验证 String backUrl = "http://m7sc6g.natappfree.cc/callBack"; // 向用户申请授权 String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + WxAuthUtil.APP_ID + "&redirect_uri=" + URLEncoder.encode(backUrl, "UTF-8") + "&response_type=code" + "&scope=snsapi_userinfo" + "&state=STATE#wechat_redirect"; response.sendRedirect(url); } /** * @Description: 授权的回调函数 * @auther: Sakura * @date: 2019/3/8 9:47 * @param: [request, response] * @return: java.lang.String */ @GetMapping(value = "/callBack") public String callBack(HttpServletRequest request, HttpServletResponse response) throws IOException { // 获取到授权标志code String code = request.getParameter("code"); // 通过code换取access_token String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + WxAuthUtil.APP_ID + "&secret=" + WxAuthUtil.APP_SECRET + "&code=" + code + "&grant_type=authorization_code"; JSONObject jsonObject = WxAuthUtil.doGetJson(url); String openid = jsonObject.getString("openid"); String access_token = jsonObject.getString("access_token"); String refresh_token = jsonObject.getString("refresh_token"); // 校验access_token是否失效 String checkoutUrl = "https://api.weixin.qq.com/sns/auth?access_token=" + access_token + "&openid=" + openid; JSONObject checkoutInfo = WxAuthUtil.doGetJson(checkoutUrl); System.out.println("校验信息-----" + checkoutInfo.toString()); if (!"0".equals(checkoutInfo.getString("errcode"))) { // 刷新access_token String refreshTokenUrl = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=" + openid + "&grant_type=refresh_token&refresh_token=" + refresh_token; JSONObject refreshInfo = WxAuthUtil.doGetJson(checkoutUrl); System.out.println(refreshInfo.toString()); access_token = refreshInfo.getString("access_token"); } // 使用access_token拉取用户信息 String infoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" + access_token + "&openid=" + openid + "&lang=zh_CN"; JSONObject userInfo = WxAuthUtil.doGetJson(infoUrl); System.out.println("用户数据-----" + userInfo.toString() + "\n" + "名字-----" + userInfo.getString("nickname") + "\n" + "头像-----" + userInfo.getString("headimgurl") + "\n" + "openID-----" + userInfo.getString("openid") + "\n" + "性别-----" + userInfo.getString("sex")); return "success"; } } |
下一篇:html5网站微信分享代码