昨天在做公众号扫码登录的时候,公众号需要先验证web应用的token
在网上尝试了各种方案,总是有多多少少的问题,后来经过各种方案的结合,最终得到可以验证成功的版本:
环境:springboot
1、配置服务代理(这里我用的Nginx)
代码语言:javascript复制server {
location /{
#注意,代理之后的端口必须是8080或443,否则验证失败
proxy_pass http://你的ip:8080;
}
}
2、controller
代码语言:javascript复制@Controller
@RequestMapping("/oauth")
public class OAuthController {
/**
* 微信公众号签名认证接口
* @Title: test
* @Description: TODO
* @param: @param signature
* @param: @param timestamp
* @param: @param nonce
* @param: @param echostr
* @param: @return
* @return: String
* @throws
*/
@RequestMapping("/wx")
public void test(HttpServletRequest request,HttpServletResponse response) {
String msgSignature = request.getParameter("signature");
String msgTimestamp = request.getParameter("timestamp");
String msgNonce = request.getParameter("nonce");
String echostr = request.getParameter("echostr");
PrintWriter print;
if (WeixinCheckoutUtil.verifyUrl(msgSignature, msgTimestamp, msgNonce)) {
try {
print = response.getWriter();
print.write(echostr);
print.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3、验证token,SHA-1算法
代码语言:javascript复制/**
* 签名认证工具类
* @ClassName: WeixinCheckoutUtil
* @Description:TODO
* @author: jp
* @date: 2019年6月13日 下午4:56:12
*
* @Copyright: 2019 www.tydic.com Inc. All rights reserved.
*
*/
public class WeixinCheckoutUtil {
// 与公众号配置信息中的Token要一致
private static String token = "";
/**
* 验证Token
* @param msgSignature 签名串,对应URL参数的signature
* @param timeStamp 时间戳,对应URL参数的timestamp
* @param nonce 随机串,对应URL参数的nonce
*
* @return 是否为安全签名
*/
public static boolean verifyUrl(String msgSignature, String timeStamp, String nonce) {
String signature =getSHA1(token, timeStamp, nonce);
if (!signature.equals(msgSignature)) {
throw new AesException(AesException.ValidateSignatureError);
}
return true;
}
/**
* 用SHA1算法验证Token
*
* @param token 票据
* @param timestamp 时间戳
* @param nonce 随机字符串
* @return 安全签名
*/
public static String getSHA1(String token, String timestamp, String nonce) {
try {
String[] array = new String[]{token, timestamp, nonce};
StringBuffer sb = new StringBuffer();
// 字符串排序
Arrays.sort(array);
for (int i = 0; i < 3; i ) {
sb.append(array[i]);
}
String str = sb.toString();
// SHA1签名生成
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(str.getBytes());
byte[] digest = md.digest();
StringBuffer hexstr = new StringBuffer();
String shaHex = "";
for (int i = 0; i < digest.length; i ) {
shaHex = Integer.toHexString(digest[i] & 0xFF);
if (shaHex.length() < 2) {
hexstr.append(0);
}
hexstr.append(shaHex);
}
return hexstr.toString();
} catch (Exception e) {
e.printStackTrace();
//throw new AesException(AesException.ComputeSignatureError);
}
return null;
}
}