使用微信测试号实现获取用户数据

前言

最近需要做一些和微信相关的项目,第一个需求是用户访问进来后直接获取用户基本数据并存入数据库,实现用户的自动注册,以前没有接触过微信的开发,记录一下。

看了一天文档实现用户调用接口后获取到基本信息。

===============================开始=======================================

首先去注册微信公众号测试号。

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";
    }
}

 

 搞定,代码没问题的话用微信访问natapp生成的域名+/login就可以获取到数据了。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值