mindtwo / px-user-laravel
Package for handling PX User authentication for Laravel.
Requires
- php: ^8.4|^8.5
- laravel/framework: ^12.0|^13.0
- laravel/scout: ^10.13
- mindtwo/laravel-decorator: ^3.0
- mindtwo/two-tility: ^1.0
- spatie/laravel-data: ^4.18
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.14
- laravel/sanctum: ^4.0
- mockery/mockery: ^1.5
- nunomaduro/collision: ^8.1.1
- orchestra/testbench: ^10.0.0||^11.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-arch: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
- phpstan/extension-installer: ^1.4
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
Suggests
- laravel/sanctum: The package provides a custom AuthToken Model which may be used by your application
Provides
None
Conflicts
None
Replaces
None
- dev-master
- 4.2.2
- 4.2.1
- 4.2.0
- 4.1.10
- 4.1.9
- 4.1.8
- 4.1.7
- 4.1.6
- 4.1.5
- 4.1.4
- 4.1.3
- 4.1.2
- 4.1.1
- 4.1.0
- 4.0.2
- 4.0.1
- 4.0.0
- 3.0.1
- 3.0.0
- 2.12.0
- 2.11.5
- 2.11.4
- 2.11.3
- 2.11.2
- 2.11.1
- 2.11.0
- 2.10.1
- 2.10.0
- 2.9.2
- 2.9.1
- 2.9.0
- 2.8.3
- 2.8.2
- 2.8.1
- 2.8
- 2.7.2
- 2.7.1
- 2.7.0
- 2.6.0
- 2.5.2
- 2.5.1
- 2.5
- 2.4.4
- 2.4.3
- 2.4.2
- 2.4.1
- 2.4.0
- 2.3.2
- 2.3.1
- 2.3
- 2.2.4
- 2.2.3
- 2.2.2
- 2.2.1
- 2.2.0
- 2.1.5
- 2.1.4
- 2.1.3
- 2.1.2
- 2.1.1
- 2.1
- 2.0.3
- 2.0.2
- 2.0.1
- 2.0
- 1.9.2.x-dev
- 1.9.1
- 1.9
- 1.8.1
- 1.8
- 1.7.1
- 1.7
- 1.6.1
- 1.5.6
- 1.5.5
- 1.5.4
- 1.5.3
- 1.5.2
- 1.5.1
- 1.5
- 1.4
- 1.3.8
- 1.3.7
- 1.3.6
- 1.3.5
- 1.3.4
- 1.3.3
- 1.3.2
- 1.3.1
- 1.3
- 1.2.1
- 1.2
- 1.1.5
- 1.1.4
- 1.1.3
- 1.1.2
- 1.1.1
- 1.1
- 1.0
- 0.10.3
- 0.10.2
- 0.10.1
- 0.10
- 0.9.4
- 0.9.3
- 0.9.2
- 0.9.1
- 0.9.0
- 0.8.2
- 0.8.1
- 0.8.0
- 0.7.4
- 0.7.3
- 0.7.2
- 0.7.1
- 0.7
- 0.6.1
- 0.6
- 0.5.3
- 0.5.2
- 0.5.1
- 0.5.0
- 0.4
- 0.3.0
- 0.2.3
- 0.2.2
- 0.2.1
- 0.2
- 0.1
- dev-fix/nullable-px-user-data-locale
- dev-fix/refresh-session-end-web-session
- dev-fix/scout-engine-pagination
- dev-chore/remove-legacy-product-code
- dev-feat/refresh-px-user-session
- dev-fix/skip-unhydratable-user-details
- dev-fix/invalidate-only-valid-tokens
- dev-feat/product-code-context
- dev-feat/extended-products-on-login
- dev-fix/blank-timestamps-in-user-data
- dev-feat/optional-px-user-data-fields
- dev-chore/add-ai-boost-guidelines
- dev-fix/add-utility-for-token-retrieval-and-testing
- dev-fix/logout-requests
- dev-fix/oidc-login-and-routes
- dev-fix/add-invalidate-to-logout
- dev-feat/add-call-to-logout-endpoint
- dev-fix/use-jwt-token-for-oidc
- dev-feat/oidc-client-and-refactoring
- dev-refactor/update-user-data-caching
- dev-fix/check-px-user-session
- dev-fix/px-user-session-driver-config-loads
- dev-fix/active_guard-helper
- dev-fix/eip-version
- dev-fix/user-products-endpoint
- dev-update/dependencies-and-structure
- dev-add-px-user-index
- dev-feature/eip-client
- dev-update-2.0.1
- dev-wip
- dev-feature/cache-admin-request
- dev-feature/make-request-throw-by-default
This package is auto-updated.
Last update: 2026-10-29 09:39:14 UTC
README
Installation
You can install the package via composer:
composer require mindtwo/px-user-laravel
How to use?
Publish config
To publish the modules config file simply run
php artisan vendor:publish px-user
This publishes the px-user.php config file to your projects config folder.
Configure the package
After that you should add the following keys to your .env-file:
- PX_USER_M2M
- PX_USER_TENANT
- PX_USER_DOMAIN
This keys will auto populate the respective config values.
Inside your configuration you will also find the keys:
stage which will use your APP_ENV variable and px_user_cache_time which
simply determines for how long the package is allowed to cache the user data in
minutes.
Set PX_USER_EXTENDED_PRODUCTS_ON_LOGIN=true (config key extended_products_on_login)
to request the user's extended products, e.g. products_validity, when the user is
resolved on login and token refresh. By default PX User returns the products without them.
PX_USER_PRODUCT_CODE (config key product_code, default lms) is sent as the
X-Context-Product-Code header on user search and user details requests.
Prepare the User model
First you will need to add a column px_user_id to your users table. This value is
used to retrieve the cached user data.
This is necessary since PX User only allows us to cache the user data and not to store them inside
a database, we rely on caching the data. This is done using Laravel Cache facade.
To seemlessly integrate the data for use with your User model the package provides
a trait.
use mindtwo\PxUserLaravel\Traits\UseUserDataCache; class User extends Model { use UseUserDataCache; }
This trait overrides the models getAttribute($name) method so you can use $user->lastname
even though there is no lastname column inside your users table.
Login a user
To login a user the package provides an action called PxUserLoginAction. Utilize this action
inside a controller to retrieve the user data from PX Users api.
An example for such a controller is given below:
use App\Http\Controllers\Controller; use Exception; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use mindtwo\PxUserLaravel\Actions\PxUserLoginAction; class LoginController extends Controller { public function __construct( protected PxUserLoginAction $pxUserLoginAction, ) { } /** * @param Request $request * @return \Illuminate\Http\JsonResponse * * @throws Exception */ public function login(Request $request) { // received token auth data via PX User widgets $tokenData = $request->only([ 'access_token', 'access_token_lifetime_minutes', 'access_token_expiration_utc', 'refresh_token', 'refresh_token_lifetime_minutes', 'refresh_token_expiration_utc', ]); $result = $this->pxUserLoginAction->execute($tokenData); return response()->json(['success' => $result]); } }
If the value for $result is true you can now access authenticated user
via Laravel's Auth facade.
Keep the session alive
PX access tokens are short-lived. On stateful web routes (admin panels, Nova) add the
RefreshPxUserSession middleware. It refreshes the authenticated user's PX tokens once
they expire within refresh_leeway seconds (PX_USER_REFRESH_LEEWAY, default 60).
When the user is left without a valid token, it logs them out and ends the session, then
passes the request on as a guest, so the authentication middleware answers the guest the
way it always does (redirect to the login page, 401 for JSON requests). The package adds
the middleware to the middleware priority right before AuthenticatesRequests, so it runs
before auth wherever it is listed; Laravel would otherwise move auth ahead of it in the
web group:
use mindtwo\PxUserLaravel\Http\Middleware\RefreshPxUserSession; Route::middleware(['web', RefreshPxUserSession::class, 'auth'])->group(function () { // ... });
It uses the default guard; pass another one as a parameter (RefreshPxUserSession::class.':admin').
On a guard without a session to end, it aborts with 401 instead.
To add handling for a failed refresh, extend the middleware and override failedRefresh().
It runs after the session has ended and does nothing by default; throw from it to answer
the request yourself instead of passing it on. Add the subclass to the middleware priority
before AuthenticatesRequests too, since the package only prioritizes its own class:
use Illuminate\Http\Request; use mindtwo\PxUserLaravel\Contracts\PxUser; use mindtwo\PxUserLaravel\Http\Middleware\RefreshPxUserSession; class RefreshAdminSession extends RefreshPxUserSession { protected function failedRefresh(Request $request, PxUser $user, ?string $guard): void { logger()->info('PX session ended', ['user' => $user->getKey()]); } }
Concurrent requests refresh only once, and the user is not logged in again, so the
session id stays the same. Each refresh dispatches PxUserTokenRefreshEvent.
Keep CheckPxUserSession instead where a client holds its own PX refresh token (e.g. an
SPA calling a token-based API): a server-side refresh rotates that token and leaves the
client's copy unusable. CheckPxUserSession only checks the token and never refreshes it.
Search users with Scout
The package registers a Scout engine named px-user that searches users by name through
the PX User API. Route your searchable model to it:
use Laravel\Scout\EngineManager; use Laravel\Scout\Engines\Engine; public function searchableUsing(): Engine { return app(EngineManager::class)->engine('px-user'); }
The tenant and domain wheres set the PX context of the search:
User::search('jane')->where('tenant', $tenant)->where('domain', $domain)->get(); User::search('jane')->take(10)->get(); User::search('jane')->query(fn ($query) => $query->whereNotNull('email_verified_at'))->paginate(20);
The engine requests all matching users from PX once, then loads the matching local users
by px_user_id in the order PX returns them. Users PX finds but your database lacks are
skipped and not counted. get() honours take(), paginate() and simplePaginate() page
over the local users. A PX 404 means no matches; other PX errors are rethrown. Searches
need an authenticated PX user.
Changelog
Please see CHANGELOG for more information what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security
If you discover any security related issues, please email info@mindtwo.de instead of using the issue tracker.
Credits
License
The MIT License (MIT). Please see License File for more information.