以上方法针对微信公众号提供的测试号,若是正式号(通过认证的),可以调用以下接口替换相关步骤
https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&
scope=SCOPE&state=STATE#wechat_redirect
参考连接:https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html
验签工具类
public class WxTokenCheckUtil {
// 与接口配置信息中的Token要一致
private static String token = "guniao";
/**
* 验证签名
* @param signature 微信计算出的前面
* @param timestamp 时间戳
* @param nonce 唯一标识
* @return
*/
public static boolean checkSignature(String signature, String timestamp, String nonce) {
String[] arr = new String[] { token, timestamp, nonce };
// 将token、timestamp、nonce三个参数进行字典序排序
Arrays.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");
byte[] digest = md.digest(content.toString().getBytes());
//这是你计算出来的签名
tmpStr = byteToStr(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
//对比一下你计算出来的签名和微信的是否一致
return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
}
/**
* 将字节数组转换为十六进制字符串
*
* @param byteArray
* @return
*/
private static String byteToStr(byte[] byteArray) {
String strDigest = "";
for (int i = 0; i < byteArray.length; i++) {
strDigest += byteToHexStr(byteArray[i]);
}
return strDigest;
}
/**
* 将字节转换为十六进制字符串
*
* @param mByte
* @return
*/
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 class AuthUtil {
public static JSONObject doGetJson(String url) throws ClientProtocolException, IOException {
JSONObject jsonObject = null;
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
HttpResponse response = client.execute(httpGet);
HttpEntity entity = response.getEntity();
if (entity != null) {
String result = EntityUtils.toString(entity, "UTF-8");
jsonObject = JSONObject.fromObject(result);
}
httpGet.releaseConnection();
return jsonObject;
}
public static JSONObject doPostJson(String url, String outStr) throws ClientProtocolException, IOException {
DefaultHttpClient client = new DefaultHttpClient();
HttpPost httpost = new HttpPost(url);
JSONObject jsonObject = null;
httpost.setEntity(new StringEntity(outStr, "UTF-8"));
HttpResponse response = client.execute(httpost);
String result = EntityUtils.toString(response.getEntity(), "UTF-8");
jsonObject = JSONObject.fromObject(result);
return jsonObject;
}
}
验签接口
@RestController
@RequestMapping("/wx")
@Slf4j
public class WxTest {
/**
* 一个普通的提供验签开放接口
*/
@RequestMapping("/niptest/valid")
@ResponseBody
public void wxValidTest(HttpServletRequest request, HttpServletResponse response) {
//你可以打个日志看看
log.debug("微信进来了。。。。");
// 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
String signature = request.getParameter("signature");
// 时间戳
String timestamp = request.getParameter("timestamp");
// 随机数
String nonce = request.getParameter("nonce");
// 随机字符串
String echostr = request.getParameter("echostr");
PrintWriter out = null;
try {
out = response.getWriter();
// 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败
if (WxTokenCheckUtil.checkSignature(signature, timestamp, nonce)) {
out.print(echostr);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
out.close();
}
}
}
}
// redirect_uri = URLEncoder.encode(http://2yhb6t.natappfree.cc + '/front/wx/index.html')
https://open.weixin.qq.com/connect/oauth2/authorize?appid=appid&redirect_uri=redirect_uri&
response_type=code&scope=snsapi_userinfo#wechat_redirect
/**
* Tea微信授权成功的回调函数
*
* @param request
* @param response
* @throws IOException
*/
@RequestMapping("/callBack")
public void deGet(HttpServletRequest request, HttpServletResponse response)throws Exception {
//获取回调地址中的code
String code = request.getParameter("code");
System.out.println("code:"+code);
//拼接url
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appid + "&secret="
+ secret + "&code=" + code + "&grant_type=authorization_code";
JSONObject jsonObject = AuthUtil.doGetJson(url);
//1.获取微信用户的openid
String openid = jsonObject.getString("openid");
System.out.println("openid:"+openid);
// 业务处理:可以存到redis中,再跟每条数据关联
}
public static String obtainAccessToken() throws IOException {
String tokenData = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appid+"&secret="+secret;
// 返回的用户信息json字符串
JSONObject jsonObject = AuthUtil.doGetJson(tokenData);
return jsonObject.getString("access_token");
}
/**
* 给关注该公众好的用户发送信息
* @throws Exception
*/
public void sendTemplateInfo(String openId) throws Exception{
//获取公众号accessToken
String accessToken = obtainAccessToken();
//消息推送接口
String path = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;
//封装参数
JSONObject jsonData = new JSONObject();
jsonData.put("touser", openId);
jsonData.put("template_id", "template_id");
JSONObject data = new JSONObject();
JSONObject first = new JSONObject();
first.put("value","测试购票支付详情!");
first.put("color","#173177");
JSONObject keyword1 = new JSONObject();
keyword1.put("value","2112323832748239");
keyword1.put("color","#173177");
JSONObject keyword2 = new JSONObject();
keyword2.put("value","2022-12-22 00:00:00");
keyword2.put("color","#173177");
JSONObject keyword3 = new JSONObject();
keyword3.put("value","199.56元");
keyword3.put("color","#173177");
JSONObject keyword4 = new JSONObject();
keyword4.put("value","微信支付");
keyword4.put("color","#173177");
JSONObject remark = new JSONObject();
remark.put("value","温馨提示:请不要爽约哦!");
remark.put("color","#173177");
data.put("first",first);
data.put("keyword1",keyword1);
data.put("keyword2",keyword2);
data.put("keyword3",keyword3);
data.put("keyword4",keyword4);
data.put("remark",remark);
jsonData.put("data",data);
JSONObject jsonObject = AuthUtil.doPostJson(path, jsonData.toString());
}