微信公众号相关开发
该文章描述的内容有两部分:
一、通过扫描微信公众号提供的二维码,获取用户信息
二、微信公众号授权获取用户信息功能开发
介绍:采用微信公众号的方式接入授权,目的是利用微信公众号的简单易用。目前,微信开放平台不支持测试环境的开发,而微信公众平台支持测试环境的开发,且申请简单。因此 ,此次选择微信公众测试号的形式进行开发。
一、微信公众号二维码
要实现微信公众号的二维码,首先需要注册一个微信公众测试号,微信公众测试号官方地址如下:
微信公众测试号申请网址:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/index
申请好微信公众测试号之后,需要进行接口配置信息,该部分要求填写的是URL
与Token
。URL要求填写的是域名地址,该地址的作用是用于回调与验证。Token则可以使用随机字符填写。URL的要求,如果是有域名的,则可以直接使用自身域名;如果没有域名的,则可以使用内网穿透技术,获得一个暂时域名。内网穿透在网上教程还是比较多的,可以直接搜教程。
申请号微信公众测试号,解决完域名的问题,就可以开始编程,首先编写的是URL验证tToken的接口,该接口编写完之后,才可以在微信公众测试号页面保存接口配置信息。
验证接口代码如下:
@RequestMapping(value = "/callback")
public String callback(HttpServletRequest request) {
String signature = request.getParameter("signature");
String timestamp = request.getParameter("timestamp");
String nonce = request.getParameter("nonce");
String echostr = request.getParameter("echostr");
if (signature != null && CheckoutUtil.checkSignature(signature, timestamp, nonce)) {
return echostr;
}
// 如果返回"",则微信公众号会二次验证,最多验证三次
return "";
}
工具类代码如下:
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* 公众号配置URL和Token的验证Util
*/
public class CheckoutUtil {
// 这里写的token要与测试公众号Token 一致
private static final String token = "";
/**
* 验证签名
*/
public static boolean checkSignature(String signature, String timestamp, String nonce) {
String[] arr = new String[]{token, timestamp, nonce};
sort(arr);
StringBuilder content = new StringBuilder();
for (String s : arr) {
content.append(s);
}
MessageDigest md;
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();
}
// 将sha1加密后的字符串可与signature对比,标识该请求来源于微信
return tmpStr != null && tmpStr.equals(signature.toUpperCase());
}
/**
* 将字节数组转换为十六进制字符串
*/
private static String byteToStr(byte[] byteArray) {
StringBuilder strDigest = new StringBuilder();
for (byte b : byteArray) {
strDigest.append(byteToHexStr(b));
}
return strDigest.toString();
}
/**
* 将字节转换为十六进制字符串
*/
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];
return new String(tempArr);
}
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;
}
}
}
}
}
至此,运行该程序,callback接口为回调验证接口,讲回调接口地址填写在配置接口信息中,保存配置信息即可,此时程序会收到微信公众测试号的验证。
接下来编写获取二维码的代码,参考官方文档,编写代码如下:
/**
* 生成临时/永久二维码
* @param value 代理标识 此处传值手机号
* @param isLimitScene 是否是永久二维码 true 永久二维码 false 临时二维码
* @param time 临时二维码时长 默认604800 单位秒 2592000 =30天
* @return 更换二维码的ticket
*/
@GetMapping("wex/create_qrcode")
public Object createQrcode(String value, @RequestParam(defaultValue = "false")Boolean isLimitScene, @RequestParam(defaultValue = "604800") int time){
try {
String access_token = getAccessToken();
String url ="https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=%s";
url = String.format(url, access_token);
JSONObject param = new JSONObject();
if(isLimitScene){//永久二维码
//二维码类型,QR_SCENE为临时的整型参数值,QR_STR_SCENE为临时的字符串参数值,QR_LIMIT_SCENE为永久的整型参数值,QR_LIMIT_STR_SCENE为永久的字符串参数值
param.put("action_name","QR_LIMIT_STR_SCENE");
}else{
param.put("action_name", "QR_STR_SCENE");
param.put("expire_seconds", time);//二维码生成后的30天(即2592000秒)后过期604800
}
JSONObject scene = new JSONObject();
scene.put("scene_str", value);
JSONObject action_info = new JSONObject();
action_info.put("scene", scene);
param.put("action_info", action_info);
String result = HttpUtil.post(url, param.toJSONString());
JSONObject json = JSON.parseObject(result);
return json.toString();
}catch (Exception e){
e.printStackTrace();
}
return "";
}
private String getAccessToken() {
// appid与appsecret在微信公众测试号中可以获取
String appid = "";
String appsecret = "";
// 请求access_token,文档:https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html
String URL = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", appid, appsecret);
String res = HttpUtil.get(URL);
JSONObject object = JSON.parseObject(res);
return object.getString("access_token");
}
在这一步中,首先获取到access_token,通过access_token和参数,获取到ticket值,该值可以用来换取二维码。在获取到ticket值之后,访问接口https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET,将获取到的ticket替换到URL地址中,即可生成一个二维码。在用户扫描二维码之后,如果未关注,则需要进行关注公众号。如果已关注,则不需要关注公众号。以上步骤完成之后,回调地址中会收到一个回调,该回调中包含了openid,通过openid和access_token,则可以获取到用户信息。