PHP: 8.2.7 / Laravel 10.16.1 / Ubuntu 20.04.6 LTS
SDK installed with
composer require auth0/login:^7.8 --update-with-all-dependencies
php artisan vendor:publish --tag auth0
Context
I have a FE React SPA App served by this PHP/Laravel Back End. The same Back End also serves a simple Admin web App using Orchid Platform for Laravel
I am currently upgrading this to integrate with Auth0. The SPA logs in via Auth0, receives an Access Token and includes the Token in requests to the BE.
BE successfully validates the Token with Auth0 and I get the Auth0 ID allowing access to protected routes defined in Routes/api.php
Next task is to associate Auth0 ID with existing user models (Eloquent ORM), as per sample Repository but with an extra check to match with existing DB email field if auth0_id hasnāt been set in the DB yet.
The initial intended flow at this time will be:
- check auth0 id āsubā matches a new auth0_id field in the DB.
- if not, check if email matches existing user, and if found, update the DBs new auth_id field with the āsubā value.
- if not, add new user with available ID data from Auth0 management API.
Iām using the Auth0 React/Typescript sample SPA app as surrogate for the FE while working on this Back End.
Step 1 was to retrieve user data from the Auth0 management API as described at Backend Api Laravel API for which I added a route:
Route::get('/messages/protected', function () {
$user = auth()->id();
$profile = cache()->get($user);
if (null === $profile) {
$endpoint = Auth0::management()->users();
$profile = $endpoint->get($user);
$profile = Auth0::json($profile);
cache()->put($user, $profile, 120);
}
$name = $profile['name'] ?? 'Unknown';
$email = $profile['email'] ?? 'Unknown';
return response()->json([
'name' => $name,
'email' => $email,
'user' => (array) auth()->user(),
]);
})->middleware('auth');
This worked, returning both name and email correctly and the Auth0 version of a user, so I moved on to trying to add Auth0 to the Admin web App part of the BE following the instructions at Regular Web App Laravel
Next I wanted to integrate the User Repository following the instructions here
Nothing has gone well since then.
My repository is the same one from the docs:
<?php
declare(strict_types=1);
namespace App\Repositories;
use App\Models\User;
use Auth0\Laravel\{UserRepositoryAbstract, UserRepositoryContract};
use Illuminate\Contracts\Auth\Authenticatable;
final class UserRepository extends UserRepositoryAbstract implements UserRepositoryContract
{
public function fromAccessToken(array $user): ?Authenticatable
{
$user = User::firstOrCreate([
'auth0_id' => $user['sub'],
], [
'name' => 'name',//$user['name'],
'email' => 'email',//$user['email'],
'email_verified' => 'email_verified',//$user['email_verified'],
]);
return $user;
}
public function fromSession(array $user): ?Authenticatable
{
return User::where('auth0_id', $user['sub'])->first();
}
}
The first thing that looked odd is my IDE (VS Code) does not recognise UserRepositoryAbstract and UserRepositoryContract - Undefined types, but assuming that to be an IDE glitch I pressed on.
Processing any request gave the error "The configured Repository App\Repositories\UserRepository could not be loaded "
I stopped and started the app with php artisan serve many times, and occasional php artisan config:clear
But could not get past this error.
But on returning to today, without any code changes (or forgotten saves), I no longer get this error but instead UserRepository is loading but now failing with:
Error Undefined array key ānameā
which relates to the line:
'name' => 'name',//$user['name'],
above.
Also returning to the SPA app / API flow, name and email both now contain āUnknownā which seems to relate to the code in the ā/messages/protectedā route:
$name = $profile['name'] ?? 'Unknown';
$email = $profile['email'] ?? 'Unknown';
Both errors appear related to name and email now not being retrieved from Auth0, in the repository by whatever means the SDK uses to extract and pass that data to it, and in the API route, from the management API call.
Note, in the repository, if I add an auth0_id field to the database (the sample UserRepository assumes this field to exist but nothing in steps I followed seemed to create it, so I added my own migration to add it) and add my Auth0 id (āsubā) to my user record, It does seem to correctly retrieve and return my User details from the database as a User object, which is good.
But without the user data (email, name) either being passed to the repository by the SDK, or accessible via a cal to the management API, I am unable to associate the existing system users to their new Auth0 identities (by matching the email addresses), nor create new users in the database with sensible values for name, email, etc.
It seems that something in either the āRegular web app Laravelā set up, or adding UserRepository, has interfered with the name and email values being accessible in the either in repository or from the management API. And Iām feeling a bit stumped for where to look for clues.
Sorry for long message, but it all seems relevant.
composer.json
{
"name": "myapp/be",
"type": "project",
"description": "MyApp Backend",
"keywords": [
"framework",
"laravel"
],
"license": "MIT",
"require": {
"php": "^8.2",
"auth0/login": "^7.8",
"aws/aws-sdk-php": "^3.273",
"barryvdh/laravel-snappy": "^1.0",
"doctrine/dbal": "^3.0",
"guzzlehttp/guzzle": "^7.7",
"h4cc/wkhtmltoimage-amd64": "0.12.4",
"h4cc/wkhtmltopdf-amd64": "0.12.4",
"laravel/framework": "^10.0",
"laravel/sanctum": "^3.2",
"laravel/socialite": "^5.6",
"laravel/tinker": "^2.8",
"laravel/ui": "^4.2",
"markrogoyski/math-php": "^2.8",
"orchid/icons": "^2.2",
"orchid/platform": "^14.3",
"socialiteproviders/google": "^4.1",
"socialiteproviders/microsoft": "^4.2",
"socialiteproviders/microsoft-graph": "^4.1",
"spatie/laravel-server-side-rendering": "^1.4",
"thomasjohnkane/snooze": "^2.3",
"valorin/pwned-validator": "^1.3"
},
"require-dev": {
"barryvdh/laravel-ide-helper": "^2.13",
"laravel/telescope": "^4.14",
"nunomaduro/collision": "^6.1",
"phpunit/phpunit": "^9",
"spatie/laravel-ignition": "^2.0"
},
"config": {
"optimize-autoloader": true,
"preferred-install": "dist",
"sort-packages": true,
"allow-plugins": {
"php-http/discovery": true
}
},
"extra": {
"laravel": {
"dont-discover": [
"laravel/telescope"
]
}
},
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"minimum-stability": "dev",
"prefer-stable": true,
"scripts": {
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover --ansi"
],
"post-root-package-install": [
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"@php artisan key:generate --ansi"
],
"post-update-cmd": [
"Illuminate\\Foundation\\ComposerScripts::postUpdate",
"@php artisan ide-helper:generate",
"@php artisan ide-helper:meta"
]
}
}