服务端 Webhook
PHP Webhook
对于使用 php 的 Opencard 应用, 开发者可以参考以下 php 示例代码,来实现 Webhook 服务。
- /* jwt 库
* github地址:https://github.com/kelvinmo/simplejwt
* 假设克隆后文件夹名为:simplejwt-master
*/
<?php
//此处仅加载本需求使用到的文件
require_once "./simplejwt-master/src/SimpleJWT/Crypt/EncryptionAlgorithm.php";
require_once "./simplejwt-master/src/SimpleJWT/Crypt/KeyManagementAlgorithm.php";
require_once "./simplejwt-master/src/SimpleJWT/Crypt/Algorithm.php";
require_once "./simplejwt-master/src/SimpleJWT/Crypt/KeyEncryptionAlgorithm.php";
require_once "./simplejwt-master/src/SimpleJWT/Crypt/AESCBC_HMACSHA2.php";
require_once "./simplejwt-master/src/SimpleJWT/Crypt/AESKeyWrap.php";
require_once "./simplejwt-master/src/SimpleJWT/Crypt/AlgorithmFactory.php";
require_once "./simplejwt-master/src/SimpleJWT/JWE.php";
require_once "./simplejwt-master/src/SimpleJWT/Keys/KeySet.php";
require_once "./simplejwt-master/src/SimpleJWT/Util/Util.php";
require_once "./simplejwt-master/src/SimpleJWT/Keys/Key.php";
require_once "./simplejwt-master/src/SimpleJWT/Crypt/CryptException.php";
require_once "./simplejwt-master/src/SimpleJWT/InvalidTokenException.php";
require_once "./simplejwt-master/src/SimpleJWT/Keys/SymmetricKey.php";
require_once "./simplejwt-master/src/SimpleJWT/Crypt/KeyDerivationAlgorithm.php";
/* Webhook 基本协议实现
*
* 以下代码为示例,未妥善处理业务字段或异常等因素
*/
public function execute(){
# 配置项,测试时请修改以下配置
$arrPsks = array("MDEyMzQ1Njc4OWFiY2RlMQ");
//组建自己的 PSK_TABLE, 可根据自己的需求修改
$psk_table = array();
foreach ($arrPsks as $key => $strPsk) {
$strKey = strval($key);
$keys = new \SimpleJWT\Keys\KeySet();
$pskKey = new \SimpleJWT\Keys\SymmetricKey($strPsk, 'base64url');
$pskKey->setKeyId($strKey);
$keys->add($pskKey);
$psk_table[$strKey] = $keys;
}
$alg = "A128KW";
//获取到请求数据
$token = file_get_contents ('php://input');
//解析请求数据
$parts = explode('.', $token, 5);
if (count($parts) != 5) {
throw new InvalidTokenException('Cannot decode compact serialisation', InvalidTokenException::TOKEN_PARSE_ERROR);
}
list($protected, $encrypted_key, $iv, $ciphertext, $tag) = $parts;
//解析出 header
$jose_header = json_decode(\SimpleJWT\Util\Util::base64url_decode($protected), true);
//从 protected 字段中解出来 kid
$kid = $jose_header['kid'];
//通过 kid 确定要使用哪个解密 key
$psk = $psk_table[strval($kid)];
//用 key 解密取得解密后的内容
$jwe = \SimpleJWT\JWE::decrypt($token,$psk,$alg);
$req = json_decode( $jwe->getPlaintext(), true);
//如果资源方有多张卡片,从 req 中解析出来 srcid,处理相应的业务逻辑
if ($req['srcid'] == "123"){
//do something
$res = array(
'status' => 0,
'msg' => "",
);
$res['data'] = array(
'item_list' => array(
'title' => "故宫博物院",
'jump_url' => "/path/to/pages3",
),
);
} else {
$res = array(
'status' => 2,
'msg' => "Invalid srcid",
);
}
//处理业务响应结果
$playload = json_encode($res);
//用请求的 header 和 key 生成加密结果,保持加密算法和头内容(kid/rid)与请求一致
$jwe = new \SimpleJWT\JWE($jose_header, $playload);
$res_body = $jwe->encrypt($psk);
header("Content-type:application/jwt; charset=UTF-8");
echo ($res_body);
}