sadnub / laravel-tenancy-passport-demo

Laravel demo with Passport and Tenancy
113 stars 32 forks source link

SQLSTATE[42S02]: Base table or view not found #9

Open konrad-ch opened 4 years ago

konrad-ch commented 4 years ago

Hi, maybe its wrong place to post my issue cause your demo project works fine for me. But I have a problem when trying to build my own project based on this demo.

When i try to register a new tenant, I receive the following error:

SQLSTATE[42S02]: Base table or view not found: 1146 Table 'tenancy.oauth_clients' doesn't exist (SQL: insert into `oauth_clients` (`user_id`, `name`, `secret`, `redirect`, `personal_access_client`, `password_client`, `revoked`, `updated_at`, `created_at`)

So it looks like it has a problem with switching to right database (the new, tenant one).

It populates hostnames, migrations and websites tables just fine.

Key files (important parts): RegisterController.php

public function register(RegisterRequest $request)
    {
        $request->merge(['fqdn' => $request->fqdn . '.' . env('TENANT_URL_BASE')]);

        $this->validator($request->all())->validate();

        Tenant::create($request->input('fqdn'));

        event(new Registered($user = $this->create($request->all())));

        if ($this->registered($request, $user)) 
          ...
    }

Tenant.php

public function __construct(Website $website = null, Hostname $hostname = null)
    {

        $this->website = $website ?? $sub->website;
        $this->hostname = $hostname ?? $sub->websites->hostnames->first();
    }

    public static function create($fqdn): Tenant
    {
        // Create New Website
        $website = new Website;
        app(WebsiteRepository::class)->create($website);

        // associate the website with a hostname
        $hostname = new Hostname;
        $hostname->fqdn = $fqdn;
        app(HostnameRepository::class)->attach($hostname, $website);

        // make hostname current
        app(Environment::class)->tenant($website);

        Artisan::call('passport:install');

        return new Tenant($website, $hostname);
    }

routes/api.php

Route::group([
    'prefix' => 'auth',
], function(){
    Route::post('register', 'Api\Auth\RegisterController@register');
});

AppServiceProvider.pjp

public function register()
    {
        \Laravel\Passport\Passport::ignoreMigrations();
    }

AuthServiceProvider.php

public function boot()
    {
        $this->registerPolicies();

        \Laravel\Passport\Passport::routes(null, ['middleware' => 'tenancy.enforce']);

        $this->commands([
            \Laravel\Passport\Console\InstallCommand::class,
            \Laravel\Passport\Console\ClientCommand::class,
            \Laravel\Passport\Console\KeysCommand::class,
        ]);

        \Laravel\Passport\Passport::tokensExpireIn(\Carbon\Carbon::now()->addMinutes(10));
        \Laravel\Passport\Passport::refreshTokensExpireIn(\Carbon\Carbon::now()->addDays(1));
    }

EnforceTenancy.php

public function handle($request, Closure $next)
    {
        Config::set('database.default', 'tenancy');

        return $next($request);
    }

Kernel.php

protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
        'tenancy.enforce' => \App\Http\Middleware\EnforceTenancy::class
    ];

database.php

    'connections' => [

        'system' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],

.env

APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:8X...
APP_DEBUG=true
APP_URL=http://mypage.test
APP_PROTOCOL=https://
APP_MAIN_DOMAIN=mypage.test
TENANT_URL_BASE=http://app.mypage.test

LOG_CHANNEL=stack

DB_CONNECTION=system
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=tenancy
DB_USERNAME=root
DB_PASSWORD=root
LIMIT_UUID_LENGTH_32=1 #MySQL only

Migration files are in the right directories (like in your demo).

I use Laravel 7 with Hyn 5.4

I would appreciate any help... :)

nanaaikinson commented 4 years ago

Hello, am having the same issue. Am using laravel 7 with Hyn 5.6

konrad-ch commented 4 years ago

Hi, I haven't solved this problem but switched to https://github.com/stancl/tenancy , it's much better, try it :)

alexyapp commented 4 years ago

for anyone still struggling with this, this approach doesn't seem to work with either the latest release of laravel or passport, what worked for me was downgrading both to versions 5.8 and 7.3 respectively