# 3.3 应用请求数据签名生成方法
第三方应用访问勤策服务接口时需要对请求数据做签名处理
# 3.3.1 服务端接口数据签名生成方法
第三方应用访问勤策服务接口时需要对请求数据做签名处理,签名信息包含(access_token-服务商授权码, timestamp-访问时间戳, nonce-随机字符串, echoStr-请求数据体)。
echoStr是接口定义中的请求示例,为JSON格式数据,如获取用户可用积分接口中echoStr示例
{"user_id": "7951571222327321975","user_type":"1"}
签名方法,根据签名数据值自然顺序排序后拼接成一个字符串,然后获取SHA-1签名。示例如下:
import java.security.MessageDigest;
import java.util.Arrays;
public class OAuth2Utils
{
/**
* 根据数据生成签名信息(1.根据数据排序 2.排序后拼接成字符串生成SHA-1签名信息)
* @param accessToken 服务商授权Token
* @param timeStamp 时间戳
* @param nonce 随机字符串
* @param echoStr 请求数据体
* @return 签名信息
* @throws Exception
*/
public static String makeSignature(String accessToken, long timeStamp, String nonce, String echoStr) throws AesException
{
try {
String[] array = new String[] { accessToken, String.valueOf(timeStamp), nonce, echoStr };
StringBuffer sb = new StringBuffer();
// 字符串排序
Arrays.sort(array);
for (int i = 0; i < 4; 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)
{
throw new Exception(e.getMessage());
}
}
}
# 3.3.2 JS-SDK 数据签名生成方法
第三方应用访问勤策客户端提供的JS-SDK接口时需要生成签名信息,签名信息需要jsapi_ticket、noncestr、timestamp、url信息
注意:请求的URL中需要将URL中'?'以及后面的参数和'#'以及后面的锚点相关部分去除。示例如下:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.security.MessageDigest;
public class OAuth2JSSDKUtils
{
private static final Logger LOGGER = LoggerFactory.getLogger(OAuth2JSSDKUtils.class);
/**
* 生成JS-SDK签名
* @param str 签名字符串格式示例:
* jsapi_ticket=2020060316180943480984829434T-bba510f4f4634f8881e10caaa01212ef&noncestr=su9d51qf80sz2dxf×tamp=1591165742&url=https://api.waiqin365.com/home.html
* 注意:请求的URL中需要将URL中'?'以及后面的参数和'#'以及后面的锚点相关部分去除
*/
private static String getSHA1(String str) throws Exception
{
try
{
LOGGER.info("oAuth2准备加密字符串:" + str);
// 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);
}
LOGGER.info("oAuth2加密字符串结果:" + hexstr.toString());
return hexstr.toString();
}
catch(Exception e)
{
LOGGER.warn("获取SHA-1加密字符串失败", e);
throw e;
}
}
/**
* 获取签名信息
* @param url 当前页面请求URL
* @param jsapi_ticket ticket
* @param noncestr 随机字符串
* @param timestamp 时间戳
* @return
* @throws Exception
*/
public static String getJsApiSignature(String url, String jsapi_ticket, String noncestr, String timestamp) throws Exception
{
if(url.indexOf("?") > -1)
{
url = url.substring(0, url.indexOf("?"));
}
if(url.indexOf("#") > -1)
{
url = url.substring(0, url.indexOf("#"));
}
StringBuffer sub = new StringBuffer();
sub.append("jsapi_ticket=").append(jsapi_ticket);
sub.append("&noncestr=").append(noncestr);
sub.append("×tamp=").append(timestamp);
sub.append("&url=").append(url);
return getSHA1(sub.toString());
}
public static void main(String[] args) throws Exception
{
String url = "https://api.waiqin365.com/open/?state=user&code=202101251552898873891063184228e069af6b94415ba56b47d0a2b71064&tenant_id=5528988738910631842&app_id=app1606897590447";
String jsapi_ticket = "2021012515937937519423778872T-e79f5546d2654f05aad5b23e4b11270b";
String noncestr = "4d8023becff64674858c4a7215f26c09";
String timestamp = "1611544273";
System.out.println(getJsApiSignature(url, jsapi_ticket, noncestr, timestamp));
}
}