PHP 调用 e 签宝接口签名指南

这篇具有很好参考价值的文章主要介绍了PHP 调用 e 签宝接口签名指南。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

在 401 问题上卡了 一段时间,参考官网文档和鉴权签名计算测试也试了很久,签名确定是没错的,但是一直提示 INVALID_SIGNATURE

其实问题在于我忽略了 公共请求头格式 中 Content-MD5 部分的一句话:

GET 和 DELETE 请求且 Body 体无数据时,此参数可为 “”(空字符串)或不传此参数。

因为参数必选部分他写了 ,我就只关注这个了…害

鉴权签名计算:https://open.esign.cn/tools/signature

下面就快速列出代码了

代码部分

获取 Content-MD5

/**
 * @param string $body
 *
 * @return string 请求体字符串,如果是文件则需要 md5_file 方法并传入文件名(带路径)
 */
public function getContentMd5(string $body): string {
    return base64_encode(md5($body, true));
}

获取签名

这里我将 App Secret 直接作为形参传入了。因为请求头和 Date 可忽略,这里也直接不作处理。

/**
 * @param string $method
 * @param string $content_md5
 * @param string $content_type
 * @param string $uri
 * @param string $app_secret
 *
 * @return string
 */
public function getSignature(string $method,
                             string $content_md5, string $content_type, string $uri, string $app_secret): string {
    $string = "$method\n*/*\n$content_md5\n$content_type\n\n$uri";

    return base64_encode(hash_hmac('sha256', $string, $app_secret, true));
}

构建请求头

需注意 X-Tsign-Open-Ca-Timestamp 请求头 必需 传入毫秒级时间戳,也就是 13 位长,用 time() 方法获取的是秒级,同样会得到 401 INVALID_TIMESTAMP 的响应

/**
 * @param string $app_id
 * @param string $app_secret
 * @param string $method
 * @param string $body          这里以 JSON 作为请求体示例,如果涉及到其它类型请求,自行修改一下
 * @param string $content_type
 * @param string $uri
 *
 * @return array
 */
public function buildSignedHeaders(string $app_id,
                                   string $app_secret,
                                   string $method, string $body, string $content_type, string $uri): array {
    $contentMd5 = '';

    if (in_array($method, ['GET', 'DELETE'])) {
        $content_type = '';
    } else {
        $contentMd5 = $this->getContentMd5($body);
    }

    return [
        'Accept' => '*/*',
        'Content-MD5' => $contentMd5,
        'Content-Type' => $content_type,
        'X-Tsign-Open-App-Id' => $app_id,
        'X-Tsign-Open-Auth-Mode' => 'Signature',
        'X-Tsign-Open-Ca-Signature' => $this->getSignature($method, $contentMd5, $content_type, $uri, $app_secret),
        'X-Tsign-Open-Ca-Timestamp' => Carbon::now()->getTimestampMs()
    ];
}

如果没有 Carbon 库,可以用官方 Demo 的写法:

/**
 * @return float 返回值是个 double
 */
public function getMillisecond(): float {
    [$t1, $t2] = explode(' ', microtime());

    return (float)sprintf('%.0f', (floatval($t1) + floatval($t2)) * 1000);
}

发送请求

/**
 * @param string      $method
 * @param string      $uri
 * @param array       $data
 * @param string|null $content_type
 * @param bool        $sandbox
 *
 * @return array|null
 */
public function request(string  $method, string $uri, array $data = [],
                        ?string $content_type = 'application/json', bool $sandbox = false): ?array {
    $method = strtoupper($method); // 统一转换为大写

    $body = '';

    if ($method === 'POST') {
        if (str_starts_with($content_type, 'application/json')) {
            $body = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
        } else {
            // TODO: 其它类型的接口自行处理
        }
    }

    // 此处通过 .env 文件取配置
    $host = env('ESIGN_HOST'); // https://openapi.esign.cn
    $appId = env('ESIGN_APPID');
    $appSecret = env('ESIGN_APPSECRET');

    // 可以根据参数进入沙盒环境方便调试
    if ($sandbox) {
        $host = env('ESIGN_SANDBOX_HOST'); // https://smlopenapi.esign.cn
        $appId = env('ESIGN_SANDBOX_APPID');
        $appSecret = env('ESIGN_SANDBOX_APPSECRET');
    }

    $headers = $this->buildSignedHeaders($appId, $appSecret, $method, $body, $content_type, $uri);

    // 这里使用了 Laravel/Lumen 9+ 的内置 Http Facade,实际也是调用 GuzzleHttp 客户端,如果直接使用 Guzzle 的 Client,send 换成 request 即可
    // 可能有人会问为什么不直接用定义好的 asJson 和 post 方法,因为...他带上了 UA,得重新处理签名部分,我懒
    $response = Http::send($method, $host . $uri, [
        'headers' => $headers,
        'body' => $body // 示例仅针对 JSON 请求,其它接口需调整
    ])->body();

    $response = json_decode($response, true);

    if (json_last_error() === JSON_ERROR_NONE) {
        return $response;
    }

    return null;
}

调用

假设类名为 ESignService

// 所以 Carbon 这个库真的方便 ;)
$from= Carbon::createFromDate(2023, 12, 1)->startOfDay()->getTimestampMs();
$to = Carbon::createFromDate(2023, 12, 31)->endOfDay()->getTimestampMs();

// 此处为查询集成方企业流程列表接口
var_dump((new ESignService)->request('POST', '/v3/organizations/sign-flow-list', [
    'pageNum' => 1,
    'pageSize' => 10,
    'signFlowStartTimeFrom' => $from, // 对于这个接口,signFlowStartTimeFrom 和 signFlowStartTimeTo 是必传的,文档上必选为否又误导了
    'signFlowStartTimeTo' => $to
]));

注意: 部分接口形式带有资源路由参数,如 /v3/sign-flow/{signFlowId}/preview-file-download-url,上方代码仅供参考,中间的 signFlowId 需根据实际业务调整文章来源地址https://www.toymoban.com/news/detail-807942.html

到了这里,关于PHP 调用 e 签宝接口签名指南的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • php 接口请求一次,controller调用了两次。

    这几天开发一个数据导出功能 由于是数据导出,所以有点慢。然后发现一个问题,前端只请求一次,controller却收到了两次请求。而且第二次请求i必定失败 这就悲催了。脑子懵懵的! 由于我这就是个小活儿,于是环境就是使用的nginx+fastcgi 网上搜索了一圈,大多都是说跨域的

    2024年02月06日
    浏览(38)
  • PHP调用淘宝app商品详情原数据 API 接口

    作为互联网企业,调用淘宝APP中的数据是非常常见的。那么如何调用呢? taobao.item_get_app 公共参数 请求地址:申请调用地址 名称 类型 必须 描述 key String 是 调用key(点*击*注*册*免*费*调*用) secret String 是 调用密钥 api_name String 是 API接口名称(包括在请求地址中)[item_search

    2023年04月24日
    浏览(49)
  • Python编程实现百度AI开放平台的接口对接方法,详解和实践指南

    Python编程实现百度AI开放平台的接口对接方法,详解和实践指南 引言 百度AI开放平台提供了丰富的人工智能接口,包括语音识别、图像识别、自然语言处理等功能。本文将通过Python编程,详解如何对接百度AI开放平台的接口,并提供实际代码示例。 准备工作 在开始之前,我们

    2024年02月13日
    浏览(46)
  • 使用SSE技术调用OPENAI接口并实现流式输出,用PHP语言实现

    作为AI语言模型服务提供商,OpenAI 提供了一系列的 API 接口,其中大部分需要通过 HTTP 请求访问。对于大量数据的请求,传统的同步请求会导致网络响应变慢,无法满足实时数据处理和分析的需求。因此,为了优化这些接口的调用效率,我们可以利用 SSE(Server Sent Events) 技术来

    2024年02月11日
    浏览(47)
  • PHP/JAVA/C#调取Taobao平台API接口实例

    PHP优势: -易于学习和使用,适合快速开发 -兼容性很好,可在不同操作系统和服务器上运行 -开源且拥有庞大的社区支持,可以获得大量的教程和帮助文档 -专门用于Web开发和动态网页生成 Java优势: -适用于构建大型、复杂的应用程序 -良好的跨平台能力 -高度可靠和安全的应

    2024年02月02日
    浏览(36)
  • PHP 如何设计一个高安全的电商平台:淘宝/京东商品类API封装接口

    如何保证API接口安全 接口的安全性主要围绕Token、Timestamp和Sign三个机制展开设计,保证接口的数据不会被篡改和重复调用,下面具体来看: Token授权机制 :用户使用用户名密码登录后服务器给客户端返回一个Token(通常是UUID),并将Token-UserId以键值对的形式存放在缓存服务

    2024年02月09日
    浏览(59)
  • ssm/php/node/python基于Andriod平台的手机Web地图服务设计(源码+mysql+文档)

    本系统 (程序+源码) 带文档lw万字以上    文末可领取本课题的JAVA源码参考 选题背景: 随着移动互联网的快速发展,智能手机已经成为人们日常生活中不可或缺的工具。而地图服务作为智能手机的重要功能之一,为用户提供了方便快捷的定位、导航和地理信息查询等服务

    2024年01月21日
    浏览(45)
  • 如何设计安全可靠的开放接口---之签名(sign)

    1. 如何设计安全可靠的开放接口—之Token 2. 如何设计安全可靠的开放接口—之AppId、AppSecret 3. 如何设计安全可靠的开放接口—之签名(sign) 4. 如何设计安全可靠的开放接口【番外篇】—关于MD5应用的介绍 5. 如何设计安全可靠的开放接口—还有哪些安全保护措施 6. 如何设计安全

    2024年02月10日
    浏览(48)
  • 三方开放接口,Springboot通过AOP实现API接口的签名验证

    前言 对外开放的接口,需要验证请求方发送过来的数据确实是由发送方发起的,并且中途不能被篡改和伪造,所以才会对接口的访问进行签名验证,以保证双方获取到的原来的信息是没有经过篡改的。 实现方法 对请求的信息内容,通过MD5运算或者其他算法(必须是 不可逆的

    2024年02月07日
    浏览(52)
  • PHP SM2签名如何实现

    SM2是一种基于椭圆曲线密码算法的公钥密码体制,包括数字签名、密钥交换和公钥加密三部分。本文将介绍如何使用PHP实现SM2签名。 在开始实现SM2签名之前,确保已经安装了以下依赖: PHP 7.0 或更高版本 OpenSSL 扩展 使用一个流行的第三方库 php-gmssl 来实现SM2签名。首先,通过

    2024年02月10日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包