eloquent-filemaker首次同步数据报Basic授权头无效错误
问题现象
- 场景:Laravel项目中使用eloquent-filemaker扩展,通过FileMaker Data API将FileMaker数据同步至MySQL数据库
- 异常规律:每次首次执行自定义Artisan同步命令
php artisan sync-filemaker-db DATABASENAME时必现报错,第二次及后续重复执行同一命令时可正常完成同步,无任何报错 - 异常详情:
- 抛出异常类:
BlueFeather\EloquentFileMaker\Exceptions\FileMakerDataApiException - 错误信息:
Authorization header 'Basic' invalid - 异常触发文件行:
vendor/bluefeather/eloquent-filemaker/src/Services/FileMakerConnection.php:167 - 业务触发点:
app/Console/Commands/SyncFileMakerDB.php:93执行DATABASENAME::count()时触发
- 抛出异常类:
现有配置
1. .env文件FileMaker连接配置
FM_DB_HOST = filemaker01.server FM_DB_USERNAME = apirest FM_DB_PASSWORD = vkjfkdjskfs
2. config/database.php中FileMaker连接配置
'DATABASENAME' => [ 'driver' => 'filemaker', 'host' => env ('FM_DB_HOST', ''), 'database' => 'DATABASENAME', 'username' => env ('FM_DB_USERNAME', ''), 'password' => env ('FM_DB_PASSWORD', ''), 'prefix' => env ('FM_DB_PREFIX', ''), 'version' => env ('FM_DB_VERSION', 'vLatest'), 'protocol' => env ('FM_DB_PROTOCOL', 'https'), ],
3. 业务代码说明
- 对应FileMaker模型继承自
FMModel,已正确配置$connection、$layout与$fieldMapping - 自定义同步命令逻辑与扩展官方示例一致
初步怀疑方向
故障与扩展包的Session Token缓存机制有关:首次调用时使用了缓存中残留的失效旧Token导致Basic授权校验失败,调用失败后扩展包清除旧Token,二次调用时重新获取有效Token即可正常运行,需要确认根本原因与修复方案。
根本原因
问题确实出在扩展包自身的Token缓存逻辑缺陷:
- 扩展包从FileMaker Data API获取到会话Token后,会默认存储到Laravel缓存中,且默认缓存有效期远长于FileMaker服务端的会话有效期。FileMaker Data API会话默认15分钟无活动就会自动失效,扩展包没有对齐这个超时时间,导致缓存中经常留存已经被服务端作废的旧Token。
- 扩展包的请求逻辑没有做前置Token有效性校验,每次发起请求先直接读取缓存中的Token使用,碰到服务端返回授权错误后,才会删除缓存中的旧Token,但不会自动重试本次失败的请求,直接将异常抛出。第二次执行命令时,旧Token已经在上一次报错时被清除,扩展包重新申请了新的有效Token,因此可以正常跑通流程。
修复方案
按优先级选择任意一种方案即可解决问题:
- 方案1(最优,一劳永逸):对齐Token缓存时长与FileMaker服务端会话有效期
打开config/database.php,在对应FileMaker连接的配置数组中新增session_token_ttl配置,值设为14(单位为分钟,比FileMaker默认的15分钟会话超时短1分钟预留冗余),从根源避免缓存留存失效Token:'DATABASENAME' => [ 'driver' => 'filemaker', 'host' => env ('FM_DB_HOST', ''), 'database' => 'DATABASENAME', 'username' => env ('FM_DB_USERNAME', ''), 'password' => env ('FM_DB_PASSWORD', ''), 'prefix' => env ('FM_DB_PREFIX', ''), 'version' => env ('FM_DB_VERSION', 'vLatest'), 'protocol' => env ('FM_DB_PROTOCOL', 'https'), 'session_token_ttl' => 14, ], - 方案2(改动最小,适合定时任务场景):命令执行前主动清除旧Token
在自定义同步命令SyncFileMakerDB.php的handle()方法最开头,所有FileMaker查询逻辑执行前,先删除缓存中存储的对应连接的旧Token,强制每次执行命令时重新申请有效Token:// 引入Cache门面 use Illuminate\Support\Facades\Cache; public function handle() { // 新增该行清除对应连接的缓存Token Cache::forget('filemaker_token_DATABASENAME'); // 原有同步逻辑... } - 方案3(兼容性最好):给授权异常增加自动重试逻辑
在全局异常处理中捕获FileMakerDataApiException,判断如果是授权头无效的错误,清除旧Token后自动重试一次请求,无需手动二次执行命令。
补充说明:如果使用Redis、APCu这类长驻缓存驱动运行CLI定时任务,不要将Token缓存时长设置过长,避免进程重启、服务端会话过期后残留无效Token。
内容的提问来源于stack exchange,提问作者dejanm
相关产品推荐
相关产品推荐

