w7corp / easywechat

📦 一个 PHP 微信 SDK

Home Page:https://easywechat.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

第三方平台 多服务器,共用redis,报No component_verify_ticket found.问题

596868636 opened this issue · comments

commented

我用的环境

  • PHP 版本:8.1.0
  • overtrue/wechat 版本:6.13.1
  • 是否使用了框架?框架名称:webman

问题及现象

现有开放平台类:OpenPlatformService,把redis设置为默认缓存。

`public function __construct()
{
$this->config = config('wechat.open_platform');
$this->open_platform = new Application($this->config);
//支付回调数据接收到的问题处理
if(!empty(request())){
$symfony_request = new SymfonyRequest(request()->get(), request()->post(), [], request()->cookie(), [], [], request()->rawBody());
$symfony_request->headers = new HeaderBag(request()->header());
$this->open_platform->setRequestFromSymfonyRequest($symfony_request);
}

    //切换缓冲到redis,用于负载均衡
    $this->redis = Redis::connection('default')->client();
    $this->open_platform->setCache(new Psr16Cache(new RedisAdapter($this->redis)));
}`

现有两台服务器,一台共用的redis服务器:
A服务器,第三方平台回调指向的是这台服务器,使用正常。
在redis服务器中,可以查询到component_access_token,的确有保存,格式为二进制格式。
image

在B服务器,使用和A相同代码和配置,调用相关接口,报:No component_verify_ticket found.

一开始以为是缓存没有指向同一个或者配置错误问题,但实际写代码测试,发现并不是,而是序列化可能导致的问题,请教下,是哪里问题?

image
如上图,因为跟踪代码到EasyWeChat\OpenPlatform\ComponentAccessToken 的
`public function getToken(): string
{

    $token = $this->cache->get($this->getKey());
    if ((bool) $token && \is_string($token)) {
        return $token;
    }

    return $this->refresh();
}`

发现是$token取不到,所以有了上面的测试,同时refresh() 方法中,发现$this->verifyTicket->getTicket()也取不到,所以报了No component_verify_ticket found.

同时发现,A、B服务器互换, B服务器保存的内容是:
s:95:"ticket@@@uPNSDPLB6yMe4JJGCVW7TlS-E1Xcp7Ldn0c4UuLoelQqbYnKovIoVO85SlD0Rwtpe4axoEn";
这样的系列化结果,
而A服务器上保存的是:
上图乱码的结果,想着是哪里编码错误了?

commented

不好意思,应该是环境扩展上的问题,phpredis扩展的默认系列化格式不一致导致的,正常编排的话应该不存在这个问题,所以避免类似的环境出行,目前建议在代码配置中,强制设置redis 的 系列化方式进处理,避免不同的环境下导致的异常问题,相类似的案例供参考

commented

补充下,也要注意 intl扩展