文字文档转换成 docx (Beta)30003错误:signature not match

Viewed 398

接口文档为:https://solution.wps.cn/docs/convert/to-docx.html

accessKey:yAn***********************ZNn contentMd5:2f0d44569f998b37b9f33e1c10728d42 mediaType:application/json date:Tue, 10 Oct 2023 01:58:44 GMT

目前的错误是: {"code":30003,"message":"InvalidSignature","hint":"signature not match. expect: 707faf8bdb079d0a9113eeff69c4a5d47446da49, actual: 7bda5d2fb228ea0eb185d94cf341ee8257b260ec","extra":""}

系统应答虽然给出正确的签名,但对排查错误毫无帮助,请问技术支持能给出更好的调试建议吗?

11 Answers

遇到同样的问题

 String mediaTypeStr = "application/json;charset=utf-8";
        MediaType mediaType = MediaType.parse(mediaTypeStr);

把mediaType字段值从application/json;改为application/json;charset=utf-8后调用成功。

完整代码如下:

        /*时间(RFC1123时间格式)*/
        SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
        sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
        String date = sdf.format(new Date());
        System.out.println("date========"+date);

        JSONObject bodyJSONObeject = new JSONObject();
        bodyJSONObeject.put("url",address);
        bodyJSONObeject.put("filename",name);
        bodyJSONObeject.put("long_txt",true);
        bodyJSONObeject.put("hold_line_feed",true);
        String bodyStr=JSONObject.toJSONString(bodyJSONObeject);
        System.out.println("bodyStr:"+bodyStr);

        String contentMd5 =  SecureUtil.md5(bodyStr);
        System.out.println("contentMd5========"+contentMd5);

        String mediaTypeStr = "application/json;charset=utf-8";
        MediaType mediaType = MediaType.parse(mediaTypeStr);
        System.out.println("mediaType"+JSONObject.toJSONString(mediaType));

        String shi1Str = appSecret + contentMd5 + mediaTypeStr + date;
        System.out.println("shi1Str======"+shi1Str);
        String sha1Str = SecureUtil.sha1(shi1Str);
        System.out.println("sha1========"+sha1Str);
        String authorization="WPS-2:" + appId + ":" + sha1Str;
        System.out.println("authorization========"+authorization);

        RequestBody body = RequestBody.create(mediaType, bodyStr);
        Request request = new Request.Builder()
                .url("https://solution.wps.cn/api/developer/v1/office/convert/to/txt")
                .post(body)
                .addHeader("Date", date)
                .addHeader("Content-Md5", contentMd5)
                .addHeader("Content-Type", mediaTypeStr)
                .addHeader("Authorization", authorization)
                .build();
        OkHttpClient client = new OkHttpClient();
        Response response = client.newCall(request).execute();
        System.out.println(response.body().string());
        System.out.println("返回数据:"+JSONObject.toJSONString(response));

这个程序是可以正常运行的,谢谢了。

提供给您以下脚本,可以放到Postman Pre-request Script 中,发送请求,如下图

let access_key = "xxxxxx"
let secret_key = "xxxxxx"

wps2(pm.request, access_key, secret_key)

function wps2(request, ak, sk) {
    let content_type = "application/json"

    let date = (new Date()).toUTCString()

    let content_md5 = request.body.raw 
    ? CryptoJS.MD5(request.body.raw).toString()
    : CryptoJS.MD5(request.url.getPathWithQuery()).toString()
      
    let signature = CryptoJS.SHA1(sk+content_md5+content_type+date).toString()
    let authorzation = `WPS-2:${ak}:${signature}`
    
    // setup variable
    pm.request.headers.add({
        key: 'Date',
        value: date
    });
    pm.request.headers.add({
        key: 'Content-Type',
        value: content_type
    });
    pm.request.headers.add({
        key: 'Content-MD5',
        value: content_md5
    });
    pm.request.headers.add({
        key: 'Authorization',
        value: authorzation
    });
}

image.png

建议检查一下您的代码逻辑是否有问题,或者提供一下对应的代码片段出来,帮您分析

按照给出的pre_request_script例子,在postman中执行成功,以下是代码截图: image.png 以下是console输出的部分参数,可见请求是成功的,成功获得task ID image.png
部分参数复制出来供参考:
date
Wed, 11 Oct 2023 06:53:48 GMT

content_md5 4905a9c89e1f7b5114dd93dfa30b6980

signature 2013eb689cd7da48db9ff74ef5e54c03c78d0021

authorzation WPS-2:SX20231008AFUMSQ:2013eb689cd7da48db9ff74ef5e54c03c78d0021

你好,期望贴的是你自己实现的代码,排查的是代码问题😂。

  • postman是我提供出来是给您来比较,相同参数情况下,对比计算值的,postman脚本肯定是没问题的。
  • 你在代码中设置date参数 与 postman使用同一的时间,同时保持body参数一致,看看你代码算出的signature 是不会是和postman中生成的相同。这样来定位代码问题

我刚进行了一次回答,其中贴出JAVA代码和执行结果供参考,请解答,谢谢

以下是JAVA源码,以及关键数据的输出,可见,在JAVA环境下,代码的执行结果完全一致: image.png 以下是输出: image.png
部分数据:
Date:Wed, 11 Oct 2023 06:53:48 GMT
Content-Md5:4905a9c89e1f7b5114dd93dfa30b6980
signature:2013eb689cd7da48db9ff74ef5e54c03c78d0021
authorzation:WPS-2:SX20231008AFUMSQ:2013eb689cd7da48db9ff74ef5e54c03c78d0021
{"code":30003,"message":"InvalidSignature","hint":"signature not match. expect: 39fd727cf3b918e24159b81e31436f6e06b26b01, actual: 2013eb689cd7da48db9ff74ef5e54c03c78d0021","extra":""}

但返回错误码为30003,提示: signature not match. expect: 39fd727cf3b918e24159b81e31436f6e06b26b01, actual: 2013eb689cd7da48db9ff74ef5e54c03c78d0021

问题就出在这里,为什么同样的哈希值,POSTMAN认,JAVA接口不认?

@haoranx

正在排查中了,请稍等

请抓一下java请求的包,看下实际发送的content-type是什么

我也遇到了类似的问题,我是python,官网例子没有给出具体的例子,例子中的app_id 都是*,根本不知道哪里错了

通过postman成功调用

如果Content-Type:application/json; charset=utf-8,会提示:{"code":10003,"message":"PermissionDenied","hint":"unknown app purpose","extra":""} 如果Content-Type:application/json,则提示{"code":30003,"message":"InvalidSignature","hint":"signature not match. expect: 7248815c49afadc1b74b8824188652328972ca3c, actual: 27cc11f2af8f617530f47b95265e756990b8c97d","extra":""}

另外这个 app_key是不是应用的AppSecret

{"code":10001,"message":"InvalidArgument","hint":"","extra":""}

终于搞定了,这玩意太坑爹了

您好,该错误信息,指的是您的 sha1( app_key + Content-Md5 + Content-Type + DATE) ,这里计算有误。

  • expect表示服务器计算出来的值,actual表示您传递过来的值,二者不匹配,就会返回InvalidSignature

我知道是这个问题,但是,如何调试呢?技术文档或者报错信息没有给出任何有价值的提示,app_key + Content-Md5 + Content-Type + DATE有4个参数,到底是哪个错了? 即使不能给出提示,官方至少能给个可用的例子吧: 比如APPID为"abcd"时算出来的MD5一定是“e2fc714c4727ee9395f324cd2e7f331f”, 使用convert/to-docx接口时,Content-Type的字符串是"application/json",
当前时间是Tue, 10 Oct 2023 01:58:44 GMT,
APPKEY是"YYYYYY"
那么计算sha1的参数一定是"YYYYYe2fc714c4727ee9395f324cd2e7f331fapplication/jsonTue, 10 Oct 2023 01:58:44 GMT"
算出来的值一定是"ce3f619903928ea9bfa90dc34d4922bd71449ae6"

我希望官方能给出一个可靠的例子。技术文档提供的例子无法运行,所以用户没法验证自己每一步的算法是否正确,这么一路下来,根本不知道自己错在哪里

在我刚才给出的例子里,如果计算sha1("YYYYYe2fc714c4727ee9395f324cd2e7f331fapplication/jsonTue, 10 Oct 2023 01:58:44 GMT"),,得到的值就是"ce3f619903928ea9bfa90dc34d4922bd71449ae6",只有这样的例子,用户才知道自己的代码到底哪个步骤出了问题

AppID不用计算MD5