Laravel使用MongoDB提示command requires authentication但migrate运行正常
可能的原因及解决办法
配置缓存未更新
Laravel 执行php artisan config:cache后会生成固定的配置缓存文件,常驻运行的服务(如 PHP-FPM、Swoole、队列工作进程等)会一直读取旧缓存配置,不会自动加载.env的更新。而你执行migrate命令时是新启动的 CLI 进程,如果执行过config:clear会直接读取最新的.env配置,自然就出现两边配置不一致的情况。
解决方式:执行php artisan config:clear清除配置缓存,重启所有运行中的应用服务、队列进程。服务端环境变量覆盖
Web 服务(如 Nginx、PHP-FPM)可能配置了独立的环境变量覆盖了.env里的 MongoDB 配置。比如 Nginx 的fastcgi_param配置、PHP-FPM 的www.conf里的env[MONGO_DB_xxx]配置,都会优先于.env生效,而 CLI 环境不会加载这些服务端的变量配置,就会出现两边配置不同。
解决方式:新增一个测试路由,打印config('database.connections.mongodb')的完整配置,和 CLI 下执行php artisan tinker输出的同一项配置做对比,就能快速定位是否是配置读取差异的问题。DSN 配置优先级问题
你当前的配置里同时定义了dsn和独立的host/username/password配置项,绝大多数 Laravel MongoDB 扩展都会优先读取dsn配置,而你当前的dsn只拼接了 host 地址,没有包含用户名、密码、认证库信息,连接时自然就没有带上认证信息。至于migrate命令能正常运行,大概率是 CLI 环境下有自定义的MONGO_DB_DSN环境变量,或者你使用的扩展版本在 CLI 下的配置解析逻辑有差异。
解决方式:要么直接删除配置里的dsn项,让扩展自动通过独立配置生成完整的连接串;要么补全dsn的拼接逻辑,参考示例如下:
'dsn' => env('MONGO_DB_DSN', sprintf( 'mongodb://%s:%s@%s:%d/%s?authSource=%s', env('MONGO_DB_USERNAME'), env('MONGO_DB_PASSWORD'), env('MONGO_DB_HOST'), 27017, env('MONGO_DB_DATABASE'), env('DB_AUTHENTICATION_DATABASE', 'admin') )),
- 认证库配置被覆盖
你配置里的认证库默认读取DB_AUTHENTICATION_DATABASE环境变量,缺省值为admin,和 Docker 生成的 root 用户的认证库一致。如果 Web 环境下该变量被覆盖为业务库rte_golf,就会出现认证失败的问题,而 CLI 环境没有覆盖该变量,就可以正常认证。
解决方式:可以直接把配置里的'database' => env('DB_AUTHENTICATION_DATABASE', 'admin')硬编码为admin,避免变量覆盖的问题,或者在.env里显式声明DB_AUTHENTICATION_DATABASE=admin。
内容的提问来源于stack exchange,提问作者Raigato

