【问题标题】:Laravel: Access denied for user 'forge'@'localhost' (but no such user is used in the app)Laravel:用户'forge'@'localhost'的访问被拒绝(但应用程序中没有使用这样的用户)
【发布时间】:2020-02-02 18:20:30
【问题描述】:

我有一个运行良好的 Laravel 应用程序,但由于某些奇怪的原因,日志文件中有很多奇怪的消息:

[2019-10-04 10:24:21] production.ERROR: SQLSTATE[HY000] [1045] Access denied for user 'forge'@'localhost' (using password: NO) {"exception":"[ object] (Doctrine\DBAL\Driver\PDOException(code: 1045): SQLSTATE[HY000] [1045] 在 /var/www/html/pzw_prod 的用户 'forge'@'localhost' (使用密码: NO) 拒绝访问/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:31, PDOException(code: 1045): SQLSTATE[HY000] [1045] Access denied for user 'forge'@'l ocalhost' (使用密码: NO) 在 /var/www/html/pzw_prod/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:27)

问题是,我没有使用名为forge 的用户连接到数据库。我的.env 使用完全不同的登录名。而且,我再说一遍,一切正常:与数据库的通信按预期工作。正在成功读取和写入数据。

那么...为什么在日志文件中出现这条消息?

更新:

config('database')

$ php artisan tinker
Psy Shell v0.9.9 (PHP 7.2.22 — cli) by Justin Hileman
>>> config('database')
=> [
     "default" => "mysql",
     "connections" => [
       "sqlite" => [
         "driver" => "sqlite",
         "url" => null,
         "database" => /* CENSORED */,
         "prefix" => "",
         "foreign_key_constraints" => true,
       ],
       "mysql" => [
         "driver" => "mysql",
         "url" => null,
         "host" => "127.0.0.1",
         "port" => "3306",
         "database" => /* CENSORED */,
         "username" => "prod_pzw",
         "password" => /* CENSORED */,
         "unix_socket" => "",
         "charset" => "utf8",
         "collation" => "utf8_unicode_ci",
         "prefix" => "",
         "prefix_indexes" => true,
         "strict" => true,
         "engine" => null,
         "options" => [],
       ],
       "pgsql" => [
         "driver" => "pgsql",
         "url" => null,
         "host" => "127.0.0.1",
         "port" => "3306",
         "database" => /* CENSORED */,
         "username" => "prod_pzw",
         "password" => /* CENSORED */,
         "charset" => "utf8",
         "prefix" => "",
         "prefix_indexes" => true,
         "schema" => "public",
         "sslmode" => "prefer",
       ],
       "sqlsrv" => [
         "driver" => "sqlsrv",
         "url" => null,
         "host" => "127.0.0.1",
         "port" => "3306",
         "database" => /* CENSORED */,
         "username" => "prod_pzw",
         "password" => /* CENSORED */,
         "charset" => "utf8",
         "prefix" => "",
         "prefix_indexes" => true,
       ],
     ],
     "migrations" => "migrations",
     "redis" => [
       "client" => "predis",
       "options" => [
         "cluster" => "predis",
         "prefix" => /* CENSORED */,
       ],
       "default" => [
         "url" => null,
         "host" => "127.0.0.1",
         "password" => null,
         "port" => "6379",
         "database" => 0,
       ],
       "cache" => [
         "url" => null,
         "host" => "127.0.0.1",
         "password" => null,
         "port" => "6379",
         "database" => 1,
       ],
     ],
   ]

更新 2:

'forge' 似乎是某种默认登录。似乎有时 Laravel 没有使用来自 .env 的值。我该如何调试?

$ cat config/database.php | grep -B 5 forge
        'mysql' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
--
        'pgsql' => [
            'driver' => 'pgsql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '5432'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
--
        'sqlsrv' => [
            'driver' => 'sqlsrv',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', 'localhost'),
            'port' => env('DB_PORT', '1433'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),

【问题讨论】:

  • 转到工匠修补匠,写 config('database') 并在此处粘贴(编辑您的问题)输出。 (出于安全原因清理所有密码)
  • @EliasSoares,我用config('database')的输出更新了我的问题
  • 你试过php artisan config:clear吗?
  • @cbaconnier,不,因为我没有缓存配置(缓存是空的,我已经检查过了)。
  • 我刚刚在 Laravel 更新后遇到了这个问题。似乎 env var 的名称在某个时候发生了变化 - 它以前称为 DB_USER,但现在称为 DB_USERNAME,因此请检查您的 .env 文件是否反映了正确的 var 名称。

标签: laravel laravel-5


【解决方案1】:

过去几天我遇到了同样的问题,我想我已经解决了:

.env 中的设置并不总是出于某种原因使用,有时 Laravel 会使用 config/app.phpconfig/database.php 中的默认设置。

config/app.php:

// Change the 'SomeRandomString' to the generated key from your .env
'key' => env('APP_KEY', 'SomeRandomString'),
 
'cipher' => 'AES-256-CBC',

config/database.php

'mysql' => [
    'driver'    => 'mysql',
    'host'      => env('DB_HOST', 'localhost'),
    'database'  => env('DB_DATABASE', 'forge'),
    'username'  => env('DB_USERNAME', 'forge'),
    'password'  => env('DB_PASSWORD', ''),
    'charset'   => 'utf8',
    'collation' => 'utf8_unicode_ci',
    'prefix'    => '',
    'strict'    => false,
],

localhostdatabaseusernamepassword.env 更改为您的实际设置。

此示例适用于 MySQL,如果您使用其他数据库引擎,请改为使用这些变量。

可能有更好的解决方案(更安全?),但这是迄今为止阻止错误出现的原因。

【讨论】:

  • 好像是这样。但是为什么会发生这种情况呢?你知道如何调试这个吗?我想摆脱日志文件中的消息而不覆盖database.php中的默认值
【解决方案2】:

在多线程网络服务器中,两个 PHP 实例将共享相同的环境变量。这是一个问题,因为进程 A 可能会在进程 B 运行时关闭并将其 ENV 变量设置为 null,然后当进程 B 请求 ENV 变量时,它将返回 null,这就是 env('DB_DATABASE', 'forge')有时会导致伪造,有时会导致正确的 ENV。

更多信息hereherehere

一种解决方案是停止运行线程化 Web 服务器(即使您使用线程安全性进行编译 PHP might run functions that are not thread safe。)

但是一个快速简单的解决方法是运行:

php artisan config:cache

这将缓存您的 ENV 和配置,从而避免该问题(当缓存配置时,laravel 不会调用 getenv/putenv)。缺点是您必须在更改环境变量或配置时运行此命令。

我找到的另一个解决方案是将此行放在您的 bootstrap/app.php 文件中:

\Illuminate\Support\Env::disablePutenv();

【讨论】:

  • 我永远不会输入\Illuminate\Support\Env::disablePutenv();,因为它会降低您的应用程序速度并导致您的生产环境出现问题。
猜你喜欢
  • 1970-01-01
  • 2015-07-04
  • 1970-01-01
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-19
相关资源
最近更新 更多