coze个人版token有效期最多30天,升级团队版或企业版后可设置token为长期。
但是刷新token不是所有场景都适用,根据目前个人版权限,不支持工作流
刷新token需要创建OAuth应用,创建时应用类型选择渠道,下载证书。
在设置/发布渠道中选择企业自定义渠道管理,添加平台时可选择发布的渠道。
token刷新代码:
JWTServer
<?php
namespace app\index\server;
class jwtServer {
private $key = "";
private $algo = "HS256";
private $kid = "";
public function __construct($kid, $key, $type = "str") {
$this->kid = $kid;
$this->setkey($key, $type);
}
public function setkey($key, $type = "str") {
$usekey = false;
if ($type == "file") {
$file = $key;
if (!is_file($file)) {
throw new \Exception("file:" . $file . "not exist");
}
$usekey = file_get_contents($file);
}
if ($type == "str") {
if (!is_string($key) || empty($key)) {
throw new \Exception("set key error");
}
$usekey = $key;
}
if (empty($usekey)) {
throw new \Exception("set key fail");
}
$resource = openssl_pkey_get_private($usekey);
if (!$resource) {
throw new \Exception("key is not private key");
}
$this->key = $usekey;
}
public function setalgo($algo) {
$this->algo = $algo;
}
/**
* 生成字符串
*/
public function generate($payload) {
if (empty($this->key)) {
throw new \Exception("key not set");
}
$header = $this->getHeader();
$payload = $this->getPayload($payload);
$signature = $this->getSignature($header, $payload);
$token = $header . "." . $payload . "." . $signature;
return $token;
}
private function getHeader() {
if (empty($this->kid)) {
throw new \Exception("kid is empty");
}
$typ = "JWT";
$data = [
"alg" => $this->algo,
"typ" => $typ,
"kid" => $this->kid,
];
$headerJson = json_encode($data);
$headerBase64 = $this->base64UrlEncode($headerJson);
return $headerBase64;
}
private function getPayload($payload) {
$payloadJson = json_encode($payload);
$payloadBase64 = $this->base64UrlEncode($payloadJson);
return $payloadBase64;
}
private function getSignature($headerBase64, $payloadBase64) {
// $sign = $this->getSignEncryption($headerBase64, $payloadBase64);
$sign = $this->getSignEncryption2($headerBase64, $payloadBase64);
$signBase64 = $this->base64UrlEncode($sign);
return $signBase64;
}
/**
* 签名加密 废弃
*/
private function getSignEncryption($headerBase64, $payloadBase64) {
if (empty($this->key)) {
throw new \Exception("key not set");
}
$algo = $this->algo;
$signStr = $headerBase64 . "." . $payloadBase64;
$sign = hash_hmac($algo, $signStr, $this->key, true);
return $sign;
}
public function getSignEncryption2($headerBase64, $payloadBase64) {
if (empty($this->key)) {
throw new \Exception("key not set");
}
$key = $this->key;
$signStr = $headerBase64 . "." . $payloadBase64;
openssl_sign($signStr, $encrypted, $key, OPENSSL_ALGO_SHA256);
return $encrypted;
}
/**
* Base64URL编码
*/
private function base64UrlEncode($data) {
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
/**
* Base64URL解码
*/
private function base64UrlDecode($data) {
return base64_decode(strtr($data, '-_', '+/'));
}
public function vertify($token) {
$data = explode(".", $token);
if (count($data) < 3) {
throw new \Exception("token format error");
}
list($headerBase64, $payloadBase64, $signBase64) = $data;
$header = json_decode($this->base64UrlDecode($headerBase64), true);
$payload = json_decode($this->base64UrlDecode($payloadBase64), true);
$sign = $this->base64UrlDecode($signBase64);
// $signCheck = $this->getSignEncryption($headerBase64, $payloadBase64);
$signCheck = $this->getSignEncryption2($headerBase64, $payloadBase64);
if ($sign != $signCheck) {
throw new \Exception("token error");
}
//验证时间
if (isset($payload['exp'])) {
if ($payload['exp'] > time()) {
throw new \Exception("token Failure");
}
}
return $payload;
}
}
COZE获取token
amespace app\index\server;
use app\index\model\businesstypemodel;
use think\Log;
class cozeserver {
private $oauth2token_url = "https://api.coze.cn/api/permission/oauth2/token";
private function getoauthconfig() {
$id = "id"; //id
$key = "key"; //公钥指纹
$pem_file = ROOT_PATH . "/private_key.pem";
$config = [
'id' => $id,
'key' => $key,
'pem_file' => $pem_file,
];
return $config;
}
public function gettoken($type, $username = "") {
$config = $this->getoauthconfig();
$s_jwt = new jwtServer($config['key'], $config['pem_file'], 'file');
$s_jwt->setalgo("RS256");
$max_day = 30;
$time = time();
$exp_time = strtotime("+$max_day days");
$jti = getRandomStrings();
$session_name = empty($username) ? "watercat" : $username;
$payload = [
"iss" => $config['id'], // OAuth 应用的 ID
"aud" => "api.coze.cn", // 扣子 API 的 Endpoint
"iat" => $time, // JWT 开始生效的时间,秒级时间戳
"exp" => $exp_time, // JWT 过期时间,秒级时间戳
"jti" => $jti, // 随机字符串,防止重放攻击
"session_name" => $session_name, //用户在业务侧的 UID
];
$jwtstr = $s_jwt->generate($payload);
$url = $this->oauth2token_url;
$authorization = " Bearer " . $jwtstr;
$header = [
'Authorization:' . $authorization,
'Content-Type: application/json',
];
$postdata = [
"grant_type" => "urn:ietf:params:oauth:grant-type:jwt-bearer",
// "duration_seconds" => 86399,//默认900秒
// "scope" => "",
];
$data = json_encode($postdata, 320);
$result = requestCurl($url, "post", $data, $header);
Log::info($result);
$jsondata = json_decode($result, true);
if (isset($jsondata['error'])) {
$msg = $jsondata['error_message'];
throw new \Exception($msg);
}
//解析后数据
return $jsondata;
}
}