Skip to content

[6.x] Move Laravel auth off of User element into CraftUser interface#19009

Open
riasvdv wants to merge 3 commits into
6.xfrom
feature/auth-refactor
Open

[6.x] Move Laravel auth off of User element into CraftUser interface#19009
riasvdv wants to merge 3 commits into
6.xfrom
feature/auth-refactor

Conversation

@riasvdv
Copy link
Copy Markdown
Contributor

@riasvdv riasvdv commented May 31, 2026

Description

Hooking up the User element into Laravel's auth service wasn't the best idea. It causes issues when trying to use Craft in combination with other ecosystem packages.

Using the default eloquent provider, and tying authentication methods and services around a CraftUser solves this problem and allows developers to use their own User models and authentication systems, as long as they implement the interface.

Filament also does this through one or more interfaces depending on the functionality you need.

Our integration surface is still mostly through the User Element which makes the asElement() method fairly load-bearing, but at least provides some extension point and separates Authentication from Elements.


Main Changes

  • Removed CraftCms\Cms\Auth\UserProvider; the craft guard now defaults to Laravel’s eloquent provider using CraftCms\Cms\User\Models\User.
  • Added CraftCms\Cms\User\Contracts\CraftUser and CraftUserTrait.
  • Both the user element and Eloquent user model now implement CraftUser.
  • Added Auth::craftUser() / auth('craft')->craftUser() and request()->craftUser() as the Craft-safe way to access the authenticated user.
  • Internal policies, auth methods, passkeys, user preferences, notifications, and CP code now type against CraftUser where they only need auth/user identity behavior.
  • Twig/global currentUser is still normalized back to the user element via currentUserElement(), so most templates should not change.

Integration Impact
Most plugins/integrations probably do not need changes if they use currentUser, Craft user elements, or normal Gate/can() checks.

Code should change if it uses Laravel auth directly and assumes Auth::user() or $request->user() is a CraftCms\Cms\User\Elements\User. Use:

$user = Auth::craftUser();
// or
$user = $request->craftUser();

Then use contract methods:

$userId = $user->getCraftUserId();
$isAdmin = $user->isAdmin();
$element = $user->asElement();

@riasvdv riasvdv marked this pull request as ready for review May 31, 2026 20:43
@riasvdv riasvdv requested a review from brandonkelly June 1, 2026 06:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant