【问题标题】:Laravel Subdomain Based Authentication Not working in Production基于 Laravel 子域的身份验证在生产中不起作用
【发布时间】:2019-11-10 01:36:31
【问题描述】:

我必须使用 laravel 构建一个多租户应用程序,并添加一个子域中间件来根据请求更改数据库。我已经更改了SESSION_DOMAIN='.example.com' 并将会话驱动程序更改为数据库。通过重定向到仪表板,我的应用程序完全可以在 localhost tenant.localhost:8000/login 中运行。但是在实时服务器http:\\tenant.example.com/login 中,当我登录时,它给了我以下错误。

我的 web.php

【问题讨论】:

  • 很可能不是问题,但您不应该在配置文件之外使用env()。缓存配置后,将不再加载环境文件,从而导致奇怪的观察结果。
  • 为什么会有多条注销路由(都是get)?
  • @Namoshek 抱歉,这是一条多余的注销路线。忽略它。现在我应该怎么做才能解决这个问题。
  • 删除生产 URL 中的前导点。
  • @Namoshek 前导点已在生产 URL 中删除。问题仍然存在。现在是$domain = env('APP_ENV') == 'local' ? 'localhost' : 'runnerhit.com';

标签: laravel session authentication subdomain laravel-5.7


【解决方案1】:

问题很可能是您在本地使用localhost,但在生产中使用.runnerhit.com。不同之处在于前导点 . 与路由组定义中的那个是多余的。

【讨论】:

  • 我已经删除了领先的.,但它仍然无法正常工作
【解决方案2】:

我也遇到过这种情况。请确保您在代码中使用路由名称而不是 URL 假设您的路线是:

Route::get('/','HomeController@index')->name('home.index');

使用 route('home.index') 代替 url('/')

【讨论】:

    【解决方案3】:

    我的多数据库多租户方法看起来像这样......

    .env 文件中,我添加了数据库。

    # Database: Client 1
    CLIENT_ONE_DB_CONNECTION=mysql
    CLIENT_ONE_DB_HOST=127.0.0.1
    CLIENT_ONE_DB_PORT=3306
    CLIENT_ONE_DB_DATABASE=client_one_db
    CLIENT_ONE_DB_USERNAME=root
    CLIENT_ONE_DB_PASSWORD=
    
    # Database: Client 2
    CLIENT_TWO_DB_CONNECTION=mysql
    CLIENT_TWO_DB_HOST=127.0.0.1
    CLIENT_TWO_DB_PORT=3306
    CLIENT_TWO_DB_DATABASE=client_two_db
    CLIENT_TWO_DB_USERNAME=root
    CLIENT_TWO_DB_PASSWORD=
    

    config/database.php 文件中添加数据库。

    'client_one' => [
        'driver' => 'mysql',
        'url' => env('CLIENT_ONE_DATABASE_URL'),
        'host' => env('CLIENT_ONE_DB_HOST', '127.0.0.1'),
        'port' => env('CLIENT_ONE_DB_PORT', '3306'),
        'database' => env('CLIENT_ONE_DB_DATABASE', 'forge'),
        'username' => env('CLIENT_ONE_DB_USERNAME', 'forge'),
        'password' => env('CLIENT_ONE_DB_PASSWORD', ''),
        'unix_socket' => env('DB_SOCKET', ''),
        'charset' => 'utf8mb4',
        'collation' => 'utf8mb4_unicode_ci',
        'prefix' => '',
        'prefix_indexes' => true,
        'strict' => true,
        'engine' => null,
        'options' => extension_loaded('pdo_mysql') ? array_filter([
            PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
        ]) : [],
    ],
    
    'client_two' => [
        'driver' => 'mysql',
        'url' => env('CLIENT_TWO_DATABASE_URL'),
        'host' => env('CLIENT_TWO_DB_HOST', '127.0.0.1'),
        'port' => env('CLIENT_TWO_DB_PORT', '3306'),
        'database' => env('CLIENT_TWO_DB_DATABASE', 'forge'),
        'username' => env('CLIENT_TWO_DB_USERNAME', 'forge'),
        'password' => env('CLIENT_TWO_DB_PASSWORD', ''),
        'unix_socket' => env('DB_SOCKET', ''),
        'charset' => 'utf8mb4',
        'collation' => 'utf8mb4_unicode_ci',
        'prefix' => '',
        'prefix_indexes' => true,
        'strict' => true,
        'engine' => null,
        'options' => extension_loaded('pdo_mysql') ? array_filter([
            PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
        ]) : [],
    ],
    

    我创建了一个配置文件,用于在/config/connection.php 设置连接,如下所示...

    <?php
    
    $domain = request()->getHttpHost();
    $domain_parts = explode('.', $domain);
    $subdomain = $domain_parts[0];
    
    if ($subdomain == 'clientone') {
        config()->set('database.default', 'client_one');
    }
    
    if ($subdomain == 'clienttwo') {
        config()->set('database.default', 'client_two');
    }
    
    return ['subdomain' => $subdomain];
    
    

    就是这样。我不必弄乱路由或中间件,这两者都带来了更深层次的挑战。这种方法使所有内容都独立且简单。

    此外,通过在配置中返回 subdomain,您可以在应用的其他位置访问该常量。例如,在刀片文件中,如果您希望应用的导航栏徽标区域显示您可以使用的客户端名称...

    {{ config('connection.subdomain') }}
    

    这是我经过大量研究后选择做的事情。希望这种方法能帮助其他人做我想做的事情。

    【讨论】:

      猜你喜欢
      • 2017-02-04
      • 2020-09-28
      • 1970-01-01
      • 2014-12-31
      • 2021-12-20
      • 2015-02-25
      • 2016-10-21
      • 2017-03-29
      相关资源
      最近更新 更多