austintoddj / canvas

Publishing on your own terms
http://trycanvas.app
MIT License
3.25k stars 519 forks source link

Not working with Laravel 8 Jetsream + Fortify #851

Closed mukarramkhalid closed 4 years ago

mukarramkhalid commented 4 years ago

Hi,

I installed Laravel 8 with Jetstream which uses default database session driver out of the box.

It creates a sessions table having user_id column with type BigInt.

As soon as I login to mydomain.com/canvas/login, I get the following error.

SQLSTATE[22007]: Invalid datetime format: 1366 Incorrect integer value: 'e27c920e-45a8-4f55-8d3d-62cc6493cf5d' for column `my_db`.`sessions`.`user_id` at row 1 (SQL: update `sessions` set `payload` = YTo1OntzOjY6Il9..., `last_activity` = 1601279641, `user_id` = e27c920e-45a8-4f55-8d3d-62cc6493cf5d, `ip_address` = 127.0.0.1, `user_agent` = Mozilla/5.0 where `id` = igv0zkK9xB0J2qLuQcbCK1lAtWPQd8TODGU52wcV)

Is this package not supported with Jetstream/Fortify yet, or am I missing something?

Thanks.

austintoddj commented 4 years ago

Canvas supports Laravel 6/7/8. It shouldn't hit anything other than it's own tables in the database.

I just did a fresh install of a Laravel 8 app with Jetstream/Fortify included, and didn't run into any issues. Can you tell me more about the setup you used?

Since Canvas uses its own authentication system, it should really be a standalone entity, separated from the rest of the application. I know that Laravel uses integers as typical user IDs, while Canvas uses a UUID as the primary key on canvas_users.

Edgarborras94 commented 4 years ago

Yep, happened something similar to me, Laravel 8 latest Jetstream + livewire latest Fresh install

SQLSTATE[01000]: Warning: 1265 Data truncated for column 'user_id' at row 1 (SQL: update `sessions` set `payload` = YTo5OntzOjY6Il90b2tlbiI7czo0MDoiekVZeFE0RVMwNWNTaFY1UjZBaFBSQ1Fob2pOOW5Rc1JXeXpJYVh3QiI7czo5OiJfcHJldmlvdXMiO2E6MTp7czozOiJ1cmwiO3M6MzA6Imh0dHBzOi8vZWRnYXJib3JyYXMuY29tL2NhbnZhcyI7fXM6NjoiX2ZsYXNoIjthOjI6e3M6Mzoib2xkIjthOjA6e31zOjM6Im5ldyI7YTowOnt9fXM6NTA6ImxvZ2luX3dlYl81OWJhMzZhZGRjMmIyZjk0MDE1ODBmMDE0YzdmNThlYTRlMzA5ODlkIjtpOjE7czoxNzoicGFzc3dvcmRfaGFzaF93ZWIiO3M6NjA6IiQyeSQxMCR6QjFYdHlkYU4uOWdiTFVYY1NtVTBlTTlGdnp6L3dmdTNHTjQwajNRSHY1WEIyWE9ENk1GNiI7czoyMToicGFzc3dvcmRfaGFzaF9zYW5jdHVtIjtzOjYwOiIkMnkkMTAkekIxWHR5ZGFOLjlnYkxVWGNTbVUwZU05RnZ6ei93ZnUzR040MGozUUh2NVhCMlhPRDZNRjYiO3M6MzoidXJsIjthOjE6e3M6ODoiaW50ZW5kZWQiO3M6MzA6Imh0dHBzOi8vZWRnYXJib3JyYXMuY29tL2NhbnZhcyI7fXM6NTM6ImxvZ2luX2NhbnZhc181OWJhMzZhZGRjMmIyZjk0MDE1ODBmMDE0YzdmNThlYTRlMzA5ODlkIjtzOjM2OiIyOTY4N2RhOC03YTY0LTRjOGMtODNhZC02NzM1OTlhNzVmMDYiO3M6MjA6InBhc3N3b3JkX2hhc2hfY2FudmFzIjtzOjYwOiIkMnkkMTAkdGtXYjlhNmpORW9saWhxejBNMFRVZWsuY0pvazFCU3FVUjRZQXVvZVVIMWIwdWk0QmRuQXkiO30=, `last_activity` = 1601325999, `user_id` = 29687da8-7a64-4c8c-83ad-673599a75f06, `ip_address` = 121.0.0.0, `user_agent` = Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/localhost Safari/537.36 where `id` = v7PRb7E4narWssdo3yIAIiFo0qMsQevEBsAHlTtx)

Something tries to add a session to the canvas user and then fails 🤔

I will update shortly

austintoddj commented 4 years ago

Do you have any route middleware other than web in config/canvas.php? The only thing I can think of is a default auth being applied to Canvas, in which case it's not needed.

Edgarborras94 commented 4 years ago

Do you have any route middleware other than web in config/canvas.php? The only thing I can think of is a default auth being applied to Canvas, in which case it's not needed.

Nope, only web in the array. Modified the ID column in the database to integer and now works. Seems funny that behaves different on each one... 🤔

Update with more info: image It actually creates a session (but without user_id obviously)

The problem starts with this middleware: Illuminate\Session\Middleware\StartSession:62

Edgarborras94 commented 4 years ago
'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            \Laravel\Jetstream\Http\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

Gotcha! the StartSession Middleware is inside the webmiddleware group!

austintoddj commented 4 years ago

So, I wonder if you make a new middleware group, call it canvas, add any necessary middleware, exclude Jetstream, then replace web and add canvas to the config/canvas.php file.

Perhaps that would separate the concerns?

Edgarborras94 commented 4 years ago

Tried removing one by one, resulting in removing every middleware except SubstituteBindings and errors occurs:

Undefined variable: errors (View: .../vendor/austintoddj/canvas/resources/views/auth/login.blade.php)

I'm don't have enough knowledge of laravel core to try to fix this... maybe we can disable sessions in anyway? This seems tricky u.u

austintoddj commented 4 years ago

Let me see what I can do.

austintoddj commented 4 years ago

It looks like when Jestream is installed, configureSession() is called here and sets your application up to utilize the database for sessions instead of the default file option in a fresh Laravel installation.

If you change the following line in the .env file from:

SESSION_DRIVER=database

...to:

SESSION_DRIVER=file

...the packages will work together. I'm not entirely sure at this point what impact that'll have on your usage of Jetstream or to what extent its features will be limited.

An alternative solution posted by @JeremyCHB is to use https://github.com/goldspecdigital/laravel-eloquent-uuid to override the User model and the user/session migrations tables to use UUID in the core Laravel app.

jhoskins98 commented 4 years ago

Quick note - The session table (in MySQL) is configured in as a BigInt. Changing it to a Char/String makes it function with both Laravel and Canvas login. Seems like the file used for session accepts both UUID (Canvas) and BitInt (Laravel) for user_id and by having two different types of logins keeps them separate. Looking at the session database while logging in and out of the two sides, there is only a single session key and user_id has the most recent one used.

austintoddj commented 4 years ago

Good catch @jhoskins98. I'll close this out @mukarramkhalid since it seems to be resolved with the above solutions, but if you run into anything else feel free to open another issue.