腾讯地图WebServiceAPI Key配置签名校验DEMO

准备工作

/**
*	参数常量
*/
public class TencentMapConstant {
    /** KEY */
    public static final String KEY = "M2OBZ-5EXK7-CWSX2-H5S2N-WALLF-*****";
    /** SecretKey (SK) */
    public static final String SK = "6S7I4XfPMccif1zl8pY7vWofEW*****";
    /** 域名 */
    public static final String HOST = "https://apis.map.qq.com";
    /** 逆地址解析api */
    public static final String GEOCODER_API = "/ws/geocoder/v1";
    /** 距离矩阵 */
    public static final String DISTANCE_API = "/ws/distance/v1/matrix";
    /** IP定位 */
    public static final String IP_LOCATION_API = "/ws/location/v1/ip";
}
/**
*	通用返回类
*/
@Data
public class TencentMapResult<T> {
    /**
     * 状态码,0为正常,其它为异常
     */
    private Integer status;

    /**
     * 状态说明
     */
    private String message;

    /**
     * 本次请求的唯一标识
     */
    private String request_id;

    /**
     * 查询结果总数量
     */
    private Integer count;

    /**
     * 返回数据 > 数组
     */
    private T data;

    /**
     * 返回数据 > 对象
     */
    private T result;

}

main方法

public static void main(String[] args) {
        /** get请求示例 */
/*        Map<String, String> params = MapUtil.builder(new HashMap<String, String>())
                .put("location", "28.7033487,115.8660847")
                .put("key", TencentMapConstant.KEY)
                .build();
        // 生成最终请求
        String signature = TencentMapUtil.generateSignatureGet(TencentMapConstant.GEOCODER_API, params);
        String finalRequest = TencentMapConstant.HOST + TencentMapConstant.GEOCODER_API + "?" + TencentMapUtil.encodeParams(params) + "sig=" + signature;
        System.out.println(finalRequest);
        RestTemplate restTemplate = new RestTemplate();
        System.out.println(restTemplate.getForObject(finalRequest, TencentMapResult.class));*/

        /** post请求示例 */
        JSONObject requestData = new JSONObject();
        requestData.set("mode", "driving");
        requestData.set("key", TencentMapConstant.KEY);
        requestData.set("from", "32.139063,118.724270");
        requestData.set("to", "32.150763,118.734398;32.157158,118.696632");

        String signature = TencentMapUtil.generateSignaturePost(TencentMapConstant.DISTANCE_API, requestData);
        String finalRequest = TencentMapConstant.HOST + TencentMapConstant.DISTANCE_API + "?mode=driving" + "&sig=" + signature;
        System.out.println(finalRequest);
        RestTemplate restTemplate = new RestTemplate();
        System.out.println(restTemplate.postForObject(finalRequest, requestData, TencentMapResult.class));
    }

TencentMapUtil 签名生成工具类

@Slf4j
public class TencentMapUtil {
    /**
     * 签名计算(sig)_GET:
     * @param path  请求路径
     * @param params    请求参数
     * @return
     */
    public static String generateSignatureGet(String path, Map<String, String> params) {
        try {
            //将参数按照 key 进行字典序排序
            TreeMap<String, String> sortedParams = new TreeMap<>(params);
            //构建原始签名字符串
            StringBuilder rawSignatureBuilder = new StringBuilder();
            rawSignatureBuilder.append(path).append("?");
            int entryIndex = 0;
            for (Map.Entry<String, String> entry : sortedParams.entrySet()) {
                rawSignatureBuilder.append(entry.getKey()).append("=").append(entry.getValue());
                if (entryIndex < sortedParams.size() - 1) {
                    rawSignatureBuilder.append("&");
                }
                entryIndex++;
            }
            rawSignatureBuilder.append(TencentMapConstant.SK);
            String rawSignature = rawSignatureBuilder.toString();

            // 计算 MD5 签名
            byte[] signatureBytes = MessageDigest.getInstance("MD5").digest(rawSignature.getBytes("UTF-8"));
            String signature = byteArrayToHexString(signatureBytes);

            return URLEncoder.encode(signature, "UTF-8"); // 进行 URL 编码
        } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
            log.error("签名计算失败: {}", e.getMessage(), e);
            return null;
        }
    }
    private static String byteArrayToHexString(byte[] bytes) {
        StringBuilder hexString = new StringBuilder();
        for (byte b : bytes) {
            hexString.append(String.format("%02x", b));
        }
        return hexString.toString();
    }

    /**
     * 对参数进行编码
     * @param params
     * @return
     */
    public static String encodeParams(Map<String, String> params) {
        TreeMap<String, String> sortedParams = new TreeMap<>(params);
        StringBuilder rawSignatureBuilder = new StringBuilder();
        for (Map.Entry<String, String> entry : sortedParams.entrySet()) {
            rawSignatureBuilder.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }
        return rawSignatureBuilder.toString();
    }

    /**
     * 签名计算(sig)_POST:
     * @param jsonObject
     */
    public static String generateSignaturePost(String path, JSONObject jsonObject) {
        //一级属性名排序字符升序排序
        Set<String> propertyNames = jsonObject.keySet();
        List<String> sortedPropertyNames = new ArrayList<>(propertyNames);
        Collections.sort(sortedPropertyNames);
        JSONObject sortedJsonObject = new JSONObject();
        for (String propertyName : sortedPropertyNames) {
            //  Value转成JSON string
            sortedJsonObject.put(propertyName, JSONUtil.toJsonStr(jsonObject.get(propertyName)));
        }
        //替换原始的 JSONObject
        jsonObject.clear();
        jsonObject.putAll(sortedJsonObject);

        //拼接成rawSignatureBuilder型的字符串
        StringBuilder rawSignatureBuilder = new StringBuilder();
        for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
            String propertyName = entry.getKey();
            String propertyValue = (String) entry.getValue();
            // 拼接成 rawSignatureBuilder 型的字符串
            rawSignatureBuilder.append(propertyName)
                    .append("=")
                    .append(propertyValue)
                    .append("&");
        }
        //去除末尾的"&"
        if (rawSignatureBuilder.length() > 0) {
            rawSignatureBuilder.deleteCharAt(rawSignatureBuilder.length() - 1);
        }

        //签名计算(sig) 请求路径+”?”+请求参数+SK
        rawSignatureBuilder.insert(0, path + "?").append(TencentMapConstant.SK);
        String rawSignature = rawSignatureBuilder.toString();

        // 计算 MD5 签名
        try {
            byte[] signatureBytes = MessageDigest.getInstance("MD5").digest(rawSignature.getBytes("UTF-8"));
            String signature = byteArrayToHexString(signatureBytes);

            return URLEncoder.encode(signature, "UTF-8"); // 进行 URL 编码
        } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
            log.error("签名计算失败: {}", e.getMessage(), e);
        }
        return null;
    }
}

附: 签名校验生成规则

<think>好的,我需要帮助用户找到腾讯云T-Sec天御的PHP示例代码或集成教程。首先,我应该回顾用户提供的引用内容,看看是否有相关信息。在引用[1]中,用户提到了他们使用ThinkPHP3.2框架,并放置了“ActivityAntiRush.php”文件在特定目录下,还进行了账号数据的填充。这说明用户可能已经有一些代码,但需要更详细的步骤或者更新的文档。 接下来,用户还提到了引用[3],其中涉及uni-app接入天域验证码的示例,包括小程序后台添加插件和项目配置。虽然这是针对小程序的,但可能表明用户对腾讯云的其他服务也有兴趣,或者希望了解类似集成流程。 用户的问题主要集中在PHP示例代码和集成文档上。我需要确保提供的答案符合系统级指令,比如正确使用LaTeX格式,结构清晰,并且生成相关问题。同时,需要引用用户提供的引用内容中的相关信息。 首先,我应该整理用户提供的引用内容中的有用信息。引用[1]提到了具体的文件放置位置和代码修改,这可能作为示例代码的一部分。引用[3]中的插件添加步骤可能对集成流程有参考价值,尽管是针对小程序的。 接下来,我需要考虑如何构建回答的结构。根据用户的要求,回答需要分步骤,结构清晰。可能需要包括获取SDK、配置账号信息、初始化服务、调用接口等步骤。同时,需要引用用户提供的引用中的内容,例如引用[1]中的文件目录放置和账号数据填充。 另外,用户可能遇到的环境配置问题,比如PHP版本和框架兼容性,应该被提及。同时,需要确保提供的示例代码符合用户使用的框架(ThinkPHP3.2),并指出可能的修改点,如命名空间调整。 最后,生成的相关问题需要围绕用户可能遇到的后续步骤,比如性能优化、错误处理、安全措施等,以及与其他腾讯云服务的结合使用。</think>根据您的需求,腾讯云T-Sec天御的PHP集成可通过以下步骤实现: ### 一、PHP集成步骤(以ThinkPHP3.2为例) 1. **获取SDK文件** 需从腾讯云控制台下载天御服务的PHP SDK文件,例如`ActivityAntiRush.php`,将其放置于框架规范目录中。 > 如引用[1]所述,文件应存放在`ThinkPHP\Library\Vendor\wx`目录下[^1] 2. **配置账号信息** 在SDK文件中填充腾讯云账号密钥: ```php // ActivityAntiRush.php 修改示例 private $secretKey = '您的SecretKey'; private $secretId = '您的SecretId'; private $businessId = 12345; // 注册的业务ID ``` 3. **初始化服务调用** 在控制器中调用防刷接口: ```php public function checkActivityUser() { Vendor('wx.ActivityAntiRush'); $antiService = new \ActivityAntiRush(); $result = $antiService->checkUserRisk($_POST['user_ip'], $_POST['user_id']); if($result['code'] == 0) { // 通过验证逻辑 } } ``` ### 二、核心配置要点 | 配置项 | 说明 | 示例值 | |--------------|---------------------------|-----------------------| | secretId | 云API密钥ID | AKIDz8krbsJ5yKBZQpn74WF | | secretKey | 云API密钥 | Gu5t9xGARNpq86cd98jo | | businessId | 天御控制台注册的业务ID | 12345678 | ### 三、常见问题解决 1. **签名错误(SignatureFailure)** 检查服务器时间是否与北京时间同步,误差需在5分钟内。可通过添加时间校准代码解决: ```php date_default_timezone_set('Asia/Shanghai'); ``` 2. **SDK依赖问题** 若框架缺少cURL扩展,需在`php.ini`中启用: ```ini extension=php_curl.dll ``` ### 四、进阶应用 通过引用[3]的插件集成模式,可结合天御验证码增强防护能力[^3]。例如在小程序端完成人机验证后,将验证结果`ticket`传递至PHP服务端进行二次校验
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值