官方文档
微信js接口验证需要的参数
- appId 公众号id
- noncestr 随机字符串
- timestamp 时间戳(秒)
- signature 签名
- url 当前网页的url
微信Token限制
- 微信token每天的获取次数有限,需采用redis缓存(代码中的RedisUtils自行替换)
签名校验
代码逻辑
@Slf4j
@Service
public class FrontWxService {
@Value("${wx.appid}")
private String appid;
@Value("${wx.appsecret}")
private String appsecret;
/**
* 微信分享获取签名
* @param url
* @return
*/
public Map<String,String> getSignature(String url){
//1、token
Map<String, String> token = WXUtils.getAccessToken(appid,appsecret);
//2、ticket
Map<String, String> ticket = WXUtils.JsapiTicket(token.get("accessToken"));
//3、时间戳
String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
//4、随机字符串
String noncestr = IdGen.uuid();
//5、url
String str = "jsapi_ticket="+ticket.get("ticket")+"&noncestr="+noncestr+"×tamp="+timestamp+"&url="+url;
//6、将字符串进行sha1加密
String signature = WXUtils.SHA1(str);
Map<String,String> map=new HashMap(16);
map.put("timestamp",timestamp);
map.put("noncestr",noncestr);
map.put("signature",signature);
return map;
}
}
WXUtils
@Slf4j
public class WXUtils {
public final static String GetPageAccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRET";
public final static String GetTicketUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
private static String WX_TOKEN = "XHCJ:WX:token:";
/**
* 获取token
* @param appid
* @param appsecret
* @return
*/
public static Map<String, String> getAccessToken(String appid, String appsecret) {
String requestUrl = GetPageAccessTokenUrl.replace("APPID", appid).replace("SECRET", appsecret);
HttpClient client = null;
Map<String, String> result = new HashMap<String, String>(16);
String accessToken = (String)RedisUtils.getObject(WX_TOKEN+appid);
if(StringUtils.isBlank(accessToken)){
try {
client = new DefaultHttpClient();
HttpGet httpget = new HttpGet(requestUrl);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String response = client.execute(httpget, responseHandler);
log.info("微信获取token返回,"+response);
JSONObject OpenidJSONO = JSONObject.fromObject(response);
accessToken = String.valueOf(OpenidJSONO.get("access_token"));
RedisUtils.setObject(WX_TOKEN+appid,accessToken,7200, TimeUnit.SECONDS);
} catch (Exception e) {
e.printStackTrace();
} finally {
client.getConnectionManager().shutdown();
}
}
result.put("accessToken", accessToken);
return result;
}
/**
* 获取ticket
* @param accessToken
* @return
*/
public static Map<String, String> JsapiTicket(String accessToken) {
String requestUrl = GetTicketUrl.replace("ACCESS_TOKEN", accessToken);
HttpClient client = null;
Map<String, String> result = new HashMap<String, String>();
try {
client = new DefaultHttpClient();
HttpGet httpget = new HttpGet(requestUrl);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String response = client.execute(httpget, responseHandler);
log.info("微信获取ticket返回,"+response);
JSONObject OpenidJSONO = JSONObject.fromObject(response);
String errcode = String.valueOf(OpenidJSONO.get("errcode"));
String errmsg = String.valueOf(OpenidJSONO.get("errmsg"));
String ticket = String.valueOf(OpenidJSONO.get("ticket"));
String expires_in = String.valueOf(OpenidJSONO.get("expires_in"));
result.put("errcode", errcode);
result.put("errmsg", errmsg);
result.put("ticket", ticket);
result.put("expires_in", expires_in);
} catch (Exception e) {
e.printStackTrace();
} finally {
client.getConnectionManager().shutdown();
}
return result;
}
/**
* SHA1加密
* @param decript
* @return
*/
public static String SHA1(String decript) {
try {
//传入加密类型
MessageDigest digest = MessageDigest.getInstance("SHA-1");
digest.update(decript.getBytes());
byte messageDigest[] = digest.digest();
// Create Hex String
StringBuffer hexStr = new StringBuffer();
// 字节数组转换为 十六进制数
for (int i = 0; i < messageDigest.length; i++) {
String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
if (shaHex.length() < 2) {
hexStr.append(0);
}
hexStr.append(shaHex);
}
return hexStr.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
}