背景
laravel 框架馍管。
由于某些原因,我們調(diào)用 EasyWeChat
使用 Factory
直接寫(xiě)入微信的配置信息薪韩。在上線一臺(tái)新機(jī)器之后發(fā)現(xiàn) Failed to cache access token
錯(cuò)誤确沸,看源文件描述的很清楚。是因?yàn)?access token 沒(méi)有成功寫(xiě)入緩存造成的
源碼如下
$this->getCache()->set($this->getCacheKey(), [
$this->tokenKey => $token,
'expires_in' => $lifetime,
], $lifetime - $this->safeSeconds);
if (!$this->getCache()->has($this->getCacheKey())) {
throw new RuntimeException('Failed to cache access token.');
}
但是我們其實(shí)已經(jīng)在 .env
中開(kāi)啟了 CACHE_DRIVER=redis
并且 use_laravel_cache=true
俘陷,所以開(kāi)始懷疑是 redis
的問(wèn)題罗捎,但是測(cè)試 redis
一切正常,沒(méi)有任何問(wèn)題拉盾。
github 上也有一些 issue桨菜,有人提到 $this->getCache()
獲取 cache 的方法的問(wèn)題,按照這個(gè)線索跟了一下捉偏。發(fā)現(xiàn)下面這段代碼
$this->app->singleton("wechat.{$name}.{$account}", function ($laravelApp) use ($name, $account, $config, $class) {
$app = new $class(array_merge(config('wechat.defaults', []), $config));
if (config('wechat.defaults.use_laravel_cache')) {
$app['cache'] = $laravelApp['cache.store'];
}
$app['request'] = $laravelApp['request'];
return $app;
});
當(dāng)通過(guò) Factory
傳入自定義配置倒得,而 config/wechat.php
中又沒(méi)有定義時(shí),就不會(huì)對(duì) app 賦值 cache 類
這也就導(dǎo)致 getCache()
方法夭禽,使用 EasyWeChat
內(nèi)置的緩存方案霞掺。
緩存目標(biāo)目錄為 /tmp/symfony-cache/
。而我的這臺(tái)服務(wù)不知什么原因讹躯,/tmp/
對(duì) other 用戶是沒(méi)有寫(xiě)權(quán)限的菩彬,所以就導(dǎo)致了 Failed to cache access token
的報(bào)錯(cuò)
public function getCache()
{
if ($this->cache) {
return $this->cache;
}
if (property_exists($this, 'app') && $this->app instanceof ServiceContainer && isset($this->app['cache'])) {
$this->setCache($this->app['cache']);
// Fix PHPStan error
assert($this->cache instanceof \Psr\SimpleCache\CacheInterface);
return $this->cache;
}
return $this->cache = $this->createDefaultCache();
}
解決方案
chmod 777 /tmp && chmod o+t /tmp
由于我碰到的問(wèn)題僅是 /tmp 權(quán)限問(wèn)題,所以此方案即可潮梯。不代表適用于全部類型問(wèn)題
chmod o+t /tmp
加t
權(quán)限是為了防止非root
用戶刪除該目錄