package com.ruoyi.iot.util; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.Base64; import java.util.concurrent.TimeUnit; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import org.springframework.stereotype.Component; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.http.HttpUtils; import com.ruoyi.common.utils.spring.SpringUtils; @Component public class TokenUtil { /** 缓存token */ private static String cachedToken; /** token过期时间 */ private static long tokenExpirationTime; public static String getToken() { /** 判断token是否过期,如果不过期直接返回全局缓存token,如果过期重新获取token保存到全局缓存token中并更新过期时间*/ try { if (isTokenExpired()) { String resourceName = SpringUtils.getRequiredProperty("iot.resourceName"); String version = SpringUtils.getRequiredProperty("iot.version"); String accessKey = SpringUtils.getRequiredProperty("iot.accessKey"); long expirationTimeInSeconds = TimeUnit.DAYS.toSeconds(Long.parseLong(SpringUtils.getRequiredProperty("iot.daysToExpire"))); String expirationTime = String.valueOf(System.currentTimeMillis() / 1000 + expirationTimeInSeconds); String signatureMethod = SignatureMethod.SHA256.name().toLowerCase();//签名方式 StringBuilder sb = new StringBuilder(); String res = URLEncoder.encode(resourceName, "UTF-8"); String sig = URLEncoder.encode(generatorSignature(version, resourceName, expirationTime, accessKey, signatureMethod), "UTF-8"); sb.append("version=") .append(version) .append("&res=") .append(res) .append("&et=") .append(expirationTime) .append("&method=") .append(signatureMethod) .append("&sign=") .append(sig); cachedToken = sb.toString(); // 更新 token 过期时间 tokenExpirationTime = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(expirationTimeInSeconds); return cachedToken; } return cachedToken; } catch (Exception e) { throw new ServiceException("获取OneNet token失败:" + e.getMessage()); } } public static String generatorSignature(String version, String resourceName, String expirationTime, String accessKey, String signatureMethod) throws NoSuchAlgorithmException, InvalidKeyException { String encryptText = expirationTime + "\n" + signatureMethod + "\n" + resourceName + "\n" + version; String signature; byte[] bytes = HmacEncrypt(encryptText, accessKey, signatureMethod); signature = Base64.getEncoder().encodeToString(bytes); return signature; } public static byte[] HmacEncrypt(String data, String key, String signatureMethod) throws NoSuchAlgorithmException, InvalidKeyException { //根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称 SecretKeySpec signinKey = null; signinKey = new SecretKeySpec(Base64.getDecoder().decode(key), "Hmac" + signatureMethod.toUpperCase()); //生成一个指定 Mac 算法 的 Mac 对象 Mac mac = null; mac = Mac.getInstance("Hmac" + signatureMethod.toUpperCase()); //用给定密钥初始化 Mac 对象 mac.init(signinKey); //完成 Mac 操作 return mac.doFinal(data.getBytes()); } public enum SignatureMethod { SHA1, MD5, SHA256; } /**判断token是否过期*/ private static boolean isTokenExpired() { return cachedToken == null || System.currentTimeMillis() > tokenExpirationTime; } public static void main(String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException { String token = getToken(); System.out.println("Authorization:" + token); String iotUrl = "https://iot-api.heclouds.com/datapoint"; String rspStr = HttpUtils.sendGet(iotUrl, token, Constants.UTF8); HttpUtils.sendPostWithToken(iotUrl,"open",token); } }