98 lines
3.0 KiB
PHP
98 lines
3.0 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace api {
|
|
final class Httpcurl
|
|
{
|
|
public static array $requests = [];
|
|
public static array $responses = [];
|
|
|
|
public static function request($url, $type, $data = false, $header = [], $timeout = 0): array
|
|
{
|
|
self::$requests[] = compact('url', 'type', 'data', 'header', 'timeout');
|
|
$body = array_shift(self::$responses);
|
|
return [json_encode($body, JSON_UNESCAPED_UNICODE), '', ['http_code' => 200], 0, ''];
|
|
}
|
|
}
|
|
}
|
|
|
|
namespace think\facade {
|
|
final class Cache
|
|
{
|
|
public static array $items = [];
|
|
|
|
public static function get(string $key, $default = null)
|
|
{
|
|
return self::$items[$key] ?? $default;
|
|
}
|
|
|
|
public static function set(string $key, $value, $ttl = null): bool
|
|
{
|
|
self::$items[$key] = $value;
|
|
return true;
|
|
}
|
|
|
|
public static function delete(string $key): bool
|
|
{
|
|
unset(self::$items[$key]);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
final class Log
|
|
{
|
|
public static array $warnings = [];
|
|
|
|
public static function warning(string $message): void
|
|
{
|
|
self::$warnings[] = $message;
|
|
}
|
|
|
|
public static function error(string $message): void
|
|
{
|
|
}
|
|
}
|
|
}
|
|
|
|
namespace {
|
|
require __DIR__ . '/../app/service/MiniProgramWechatService.php';
|
|
|
|
use api\Httpcurl;
|
|
use app\service\MiniProgramWechatService;
|
|
use think\facade\Cache;
|
|
|
|
$appid = 'wx-test-appid';
|
|
$cacheKey = 'miniapp_stable_access_token_' . md5('evus_bj_mp|' . $appid);
|
|
Cache::$items[$cacheKey] = 'stale-token';
|
|
Httpcurl::$responses = [
|
|
['errcode' => 40001, 'errmsg' => 'invalid credential'],
|
|
['access_token' => 'fresh-stable-token', 'expires_in' => 7200],
|
|
['errcode' => 0, 'phone_info' => ['purePhoneNumber' => '18668962632']],
|
|
];
|
|
|
|
$service = new MiniProgramWechatService('evus_bj_mp', [
|
|
'wechat_appid' => $appid,
|
|
'wechat_secret' => 'test-secret',
|
|
]);
|
|
$mobile = $service->mobileByPhoneCode('single-use-phone-code');
|
|
|
|
if ($mobile !== '18668962632') {
|
|
throw new RuntimeException('Phone lookup must retry once after an invalid access token');
|
|
}
|
|
if (count(Httpcurl::$requests) !== 3) {
|
|
throw new RuntimeException('Phone lookup must make exactly one retry');
|
|
}
|
|
if (!str_contains((string)Httpcurl::$requests[1]['url'], '/cgi-bin/stable_token')) {
|
|
throw new RuntimeException('Token refresh must use the stable access token endpoint');
|
|
}
|
|
$refreshBody = json_decode((string)Httpcurl::$requests[1]['data'], true);
|
|
if (($refreshBody['force_refresh'] ?? null) !== true) {
|
|
throw new RuntimeException('Invalid access token retry must force one stable token refresh');
|
|
}
|
|
if ((Cache::$items[$cacheKey] ?? '') !== 'fresh-stable-token') {
|
|
throw new RuntimeException('Refreshed stable access token must be cached');
|
|
}
|
|
|
|
echo "Wechat phone token retry self-check passed\n";
|
|
}
|