Java实现微信扫一扫功能获取签名
作者:互联网
目录
4)获取当前时间戳,记得除以1000(10位数) 例如:1626139722
一、流程:
1) 前端请求后台接口,传入url
2) 后端接收请求,处理业务逻辑,返回签名等参数
1.获取token
2.拿token获取ticket
3.获取随机字符串(用自带的UUID就行)
4.获取当前时间戳,记得除以1000(10位数) 例如:1626139722
5.拼接参数(url是前端传过来的)
String context = "jsapi_ticket=xxxx&noncestr=xxxx×tamp=xxxx&url=xxxx“
6.参数SHA1加密
7.封装,返回前端
二、分步骤解析:
如果不想了解,直接去最下面Cope完整代码
1)获取token
appid、secret、grant_type这三个值都是固定值
前两个值是微信公众号开发者平台上的凭据,AppId 和 AppSecret
微信公众平台凭据调试工具:https://mp.weixin.qq.com/debug
------------------------------------------------------------------------------------------------------------
appid:公众号的id
secret:公众号的秘钥
grant_type:授权码发放类型(固定值:client_credential)
grant_type=client_credential
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
private static JsonParser parse = new JsonParser();
/**
* 获取 token
* @return
*/
public static String getToken() {
// https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=xxxx&secret=xxxx
String url = ACCESS_TOKEN_URL + "?grant_type=" + GRANT_TYPE + "&appid=" + APPID + "&secret=" + SECRET;
//请求链接获取token,这个httpGetForJson()方法去完整代码中找
String response = httpGetForJson(url);
return ((JsonObject) parse.parse(response)).get(ACCESS_TOKEN_KEY).getAsString();
}
2)拿token获取ticket
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
private static JsonParser parse = new JsonParser();
/**
* 获取 ticket
* @param token
* @return
*/
public static String getTicket(String token) {
// https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=xxxx&type=jsapi
String url = TICKET_URL + "?access_token=" + token + "&type=" + TYPE;
//请求链接获取token,这个httpGetForJson()方法去完整代码中找
String response = httpGetForJson(url);
return ((JsonObject) parse.parse(response)).get(TICKET_KEY).getAsString();
}
3)获取随机字符串(用自带的UUID就行)
import java.util.UUID;
String nonceStr = UUID.randomUUID().toString();
4)获取当前时间戳,记得除以1000(10位数) 例如:1626139722
String timestamp = Long.toString(System.currentTimeMillis() / 1000);
5)、6)拼接参数,并加密
微信 JS 接口签名校验工具:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign
// 值是前几步骤中获取到的,url是前端传过来的
String context = "jsapi_ticket=xxxx&noncestr=xxxx×tamp=xxxx&url=xxxx";
//加密
String signature = SHA1(context);
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* SHA1加密
* @param value
* @return
*/
public static String SHA1(final String value) {
MessageDigest digest;
try {
digest = MessageDigest.getInstance("SHA-1");
digest.update(value.getBytes());
byte messageDigest[] = digest.digest();
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < messageDigest.length; i++) {
String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
if (shaHex.length() < 2) {
hexString.append(0);
}
hexString.append(shaHex);
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
三、完整代码:
直接拿来用,前端传入url直接请求
返回类型自己封装个就行,不一定直接返回Map<String, String>
WxSignatureUtil是自己封装的微信生成签名工具类
import com.smart.wechat.config.WxSignatureUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController
@RequestMapping("/wx/config")
public class WxConfigController {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* 获取微信配置
* params:前端传过来的,包含url
*/
@RequestMapping("/gerWxConfig")
public Map<String, String> gerWxConfig(@RequestBody Map<String,Object> params) {
try {
String url = String.valueOf(params.get("url"));
Map<String, String> returnMap = WxSignatureUtil.getWechatSignature(url);
return returnMap;
} catch (Exception e) {
return null;
}
}
}
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@Component
public class WxSignatureUtil {
/**
* 开发者ID,必填
* 微信公众号开发者平台上的凭据 AppId
*/
private static fianl String APPID = "xxxxxxxx";
/**
* 开发者秘钥,必填
* 微信公众号开发者平台上的凭据 AppSecret
*/
private static fianl String SECRET = "xxxxxxxx";
/**
* 授权码发放类型
*/
private static final String GRANT_TYPE = "client_credential";
/**
* 授权码类型
*/
private static final String TYPE = "jsapi";
/**
* 获取微信 TOKEN 接口
*/
private static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token";
/**
* 获取微信令牌接口
*/
private static final String TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
/**
* 请求参数名
*/
private static final String ACCESS_TOKEN_KEY = "access_token";
/**
* TICKET_KEY
*/
private static final String TICKET_KEY = "ticket";
/**
* JSON 解析
*/
private static JsonParser parse = new JsonParser();
/**
* 获取签名
* 注意 URL 一定要动态获取,不能 hardcode
* @param url
* @return
*/
public static Map<String, String> getWechatSignature(String url) {
// 获取token
String token = getToken();
// 获取ticket
String ticket = getTicket(token);
// 随机字符串
String nonceStr = UUID.randomUUID().toString();
// 时间戳
String timestamp = Long.toString(System.currentTimeMillis() / 1000);
//注意这里参数名必须全部小写,且必须有序
String context = "jsapi_ticket=" + ticket + "&noncestr=" + nonceStr + "×tamp=" + timestamp + "&url=" + url;
//加密
String signature = SHA1(context);
//封装
Map<String, String> result = new HashMap<String, String>();
result.put("url", url);
result.put("jsapi_ticket", ticket);
result.put("nonceStr", nonceStr);
result.put("timestamp", timestamp);
result.put("signature", signature);
result.put("appId", APPID);
return result;
}
/**
* 获取 token
* @return
*/
public static String getToken() {
// https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=&secret=xxxxxxxxx
String url = ACCESS_TOKEN_URL + "?grant_type=" + GRANT_TYPE + "&appid=" + APPID + "&secret=" + SECRET;
//请求链接获取token
String response = httpGetForJson(url);
return ((JsonObject) parse.parse(response)).get(ACCESS_TOKEN_KEY).getAsString();
}
/**
* 获取 ticket
* @param token
* @return
*/
public static String getTicket(String token) {
// https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=xxxx&type=jsapi
String url = TICKET_URL + "?access_token=" + token + "&type=" + TYPE;
//请求链接获取token
String response = httpGetForJson(url);
return ((JsonObject) parse.parse(response)).get(TICKET_KEY).getAsString();
}
/**
* SHA1加密
* @param value
* @return
*/
public static String SHA1(final String value) {
MessageDigest digest;
try {
digest = MessageDigest.getInstance("SHA-1");
digest.update(value.getBytes());
byte messageDigest[] = digest.digest();
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < messageDigest.length; i++) {
String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
if (shaHex.length() < 2) {
hexString.append(0);
}
hexString.append(shaHex);
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
/**
* 发送请求
* @param url
* @return
*/
public static String httpGetForJson(String url) {
CloseableHttpClient httpclient = HttpClients.createDefault();
try {
// 创建 HTTPGET
HttpGet httpget = new HttpGet(url);
// 发送 GET 请求
CloseableHttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
return entity == null ? "" : EntityUtils.toString(entity);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return "";
}
}
四、总结
需要前端多配合,校验工具不一定准确,仅供参考,避坑!!!
标签:Java,String,url,微信,return,token,static,一扫,import 来源: https://blog.csdn.net/Eternal_Blue/article/details/118693895