adscore / php-common
Adscore的PHP客户端库
Requires
- php: >=7.4.0
- ext-hash: >=7.4.0
- ext-openssl: >=7.4.0
Suggests
- ext-igbinary: Required to support igbinary-encoded v5 signatures
- ext-msgpack: Required to support msgpack-encoded v5 signatures
- ext-sodium: Required to support sodium-based encryption algorithms
This package is auto-updated.
Last update: 2024-09-02 12:16:15 UTC
README
此库提供用于生成和解析Adscore签名、生成自定义请求数据包以及为服务器端集成服务提供各种实用工具的功能。
安装
通过Composer
$ composer require adscore/php-common
用法
V4签名验证
当区域的“响应签名算法”设置为“哈希”或“签名”时,意味着正在使用V4签名。它们提供了检查传入流量是否为有机和有价值的基本手段,但不携带任何附加信息。
use AdScore\Common\Signature\Signature4; use AdScore\Common\Signature\Exception\{VersionException, ParseException, VerifyException}; use AdScore\Common\Definition\Judge; /* Replace <key> with "Zone Response Key" which you might find in "Zone Encryption" page for given zone. Those keys are base64-encoded and the library expects raw binary, so we need to decode it now. */ $cryptKey = \base64_decode("<key>"); /* Three things are necessary to verify the signature - at least one IP address, User Agent string and the signature itself. */ $signature = $_GET['signature']; /* for example */ $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? ''; /* You might want to use X-Forwarded-For or other IP-forwarding headers coming from for example load balancing services, but make sure you trust them and they are not vulnerable to user modification! */ $ipAddresses = [ $_SERVER['REMOTE_ADDR'] ]; try { $parser = Signature4::createFromRequest($signature, $ipAddresses, $userAgent, $cryptKey); /* Result contains numerical result value */ $result = $parser->getResult(); /* Judge is the module evaluating final result in the form of single score. RESULTS constant contains array with human-readable descriptions of every numerical result, if needed. */ $humanReadable = Judge::RESULTS[$result]; print $humanReadable['verdict'] . ' (' . $humanReadable['name'] . ')'; } catch (VersionException $e) { /* It means that the signature is not the V4 one, check your zone settings and ensure the signatures are coming from the chosen zone. */ } catch (ParseException $e) { /* It means that the signature metadata is malformed and cannot be parsed, or contains invalid data, check for corruption underway. */ } catch (VerifyException $e) { /* Signature could not be verified - usually this is a matter of IP / user agent mismatch (or spoofing). They must be bit-exact, so even excessive whitespace or casing change can trigger the problem. */ }
V5签名解密
V5实际上是一个包含有关流量各种元数据的加密请求数据包。其解密不依赖于IP地址或用户代理字符串,因此它对通常阻止V4解码的环境变化具有免疫力。数据包中还包含判断结果,但进行集成的客户端可以根据伴随的元数据做出自己的决定。
必须明确将区域设置为V5签名,如果您看不到选项,请联系支持人员,因为我们正在根据客户需求推出此模式。该格式支持多种加密和序列化方法,其中一些包含在此存储库中,但可以根据特定需求进行扩展。
它可以以V4兼容模式集成,不使用任何V5功能(参见V4验证)
use AdScore\Common\Signature\Signature5; use AdScore\Common\Signature\Exception\{VersionException, ParseException, VerifyException}; use AdScore\Common\Definition\Judge; $cryptKey = \base64_decode("<key>"); $signature = $_GET['signature']; $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? ''; $ipAddresses = [ $_SERVER['REMOTE_ADDR'] ]; try { $parser = Signature5::createFromRequest($signature, $ipAddresses, $userAgent, $cryptKey); $result = $parser->getResult(); $humanReadable = Judge::RESULTS[$result]; print $humanReadable['verdict'] . ' (' . $humanReadable['name'] . ')'; } catch (VersionException $e) { /* It means that the signature is not the V5 one, check your zone settings and ensure the signatures are coming from the chosen zone. */ } catch (ParseException $e) { /* It means that the signature metadata is malformed and cannot be parsed, or contains invalid data, check for corruption underway. */ } catch (VerifyException $e) { /* Signature could not be verified - see error message for details. */ }
第一个区别是现在$cryptKey
也可以是Closure
实例(lambda函数),接受单个int
参数-区域ID,并返回原始键的二进制字符串。这在来自不同区域的签名在单个点处理的情况下很有用。对于V4签名,这是不可能的,因为它们不携带任何区域信息。
如我们所见,createFromRequest
也需要一个IP地址列表和用户代理字符串。这用于内置验证程序,但这次验证与解密无关。进行集成的客户端可能想用自己的实现替换验证,因此这里提供了一个扩展示例(为了可读性,没有添加任何异常处理)
use AdScore\Common\Signature\Signature5; $signature = $_GET['signature']; /* An example structure holding keys for every zone supported */ $cryptKeys = [ 123 => \base64_decode("123456789abcdefghijklmn") ]; $parser = new Signature5(); /* Parsing/decryption stage */ $parser->parse($signature, function ($zoneId) use ($cryptKeys) { if (!isset($cryptKeys[$zoneId])) { throw new RuntimeException('Unsupported zone ' . $zoneId); } return $cryptKeys[$zoneId]; }); /* The payload now contains a decrypted signature data which might be used to verify the signature */ $payload = $parser->getPayload(); /* We can still make use of built-in signature validator and only then getResult() is being populated */ $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? ''; $ipAddresses = [ $_SERVER['REMOTE_ADDR'] ]; $parser->verify($ipAddresses, $userAgent); $result = $parser->getResult();
result
字段及其相关的getResult()
获取器方法仅在成功的verify()
调用后返回结果分数。这是预期的行为,以保持与V4行为的一致性-只有当它被证明属于访客时,结果才是有效的。对于不依赖内置验证程序的自定义集成(通常更宽容),结果也存在于通过getPayload()
调用检索的数据包中,但此时集成者的责任是确保其是否可信。当所需的验证比内置验证更严格时,可以先调用verify()
,填充getResult()
值,然后进行任何附加验证。
注意:V4签名解析器也保留数据包,但它不包含任何有用的信息,只有时间戳和签名字符串;特别是-它不包含任何判断结果值,它是通过几种哈希/验证方法从签名中推导出来的。
集成
关于您在定制集成方面有任何疑问,请联系我们的support@adscore.com。请记住,我们确实需要您具备一定的技术知识,以便能够帮助您进行集成;还有其他集成方法,可能不需要任何编程,或者只需要很少的编程。