This took TOO long to figure out. Both first-party packages of Laravel, and yet unusually difficult to debug, and really simple fixes (despite a number of rabbit-holes that might have led to all sorts of refactoring).
Here's the context:
- I'd like a Jetstream app to be an Identity Server
- I'd like other Laravel apps to be able to authenticate against it
Easy right? Add Passport to the server, add socialite to the clients, job done. Well, in the end, yes - but the journey was harder than that.
composer require laravel/passport
So yes, require Passport on the server in the usual way. It isn't as disruptive to Jetstream/Sanctum as you'd think. Remember to start with a new branch/clean state, just in case.
In the User model, you will then need to replace
Passport::routes() in one of your Service Providers (RouteServiceProvider?) - in the
config/jetstream.php, change the Jetstream Guard to
config/auth.php. You need to add to the
'guards' => [ //... 'api' => [ 'driver' => 'passport', 'provider' => 'users', 'hash' => false, ], ],
In the routes file for API:
api.php change the Route middleware from
Moving to auth:api got me for ages, and was the last thing I did. Without it, you can successfully authenticate against the server, but the returned user fields will all be null when the client then uses the token.
Final thing - it could be worth overriding your default Client model to allow first-party clients to authenticate without a confirmation. You may need to adjust the logic in that override.
You can probably remove Sanctum now. Might want to check for any other uses first.
You will also need to create a way for users to create clients and tokens if you need them to - I took inspiration from this package. I didn't pull it in, but instead reworked the views and Livewire components into my app. Because.
You can use Socialite with the LaravelPassport provider as usual i.e.
- Pull in the package (you want
laravel/socialiteas well as
- Register the providers (noting you don't register the socialite provider, unless using it for e.g. GitHub)
- Register the listeners
- Register the routes
- Add the migrations to store the
refresh_tokenin your User model, or in a related model.
- Remove the login button, or supplement it with a login/register button that takes you to the the Socialite redirect.
And finally - add the necessary config. This one got me. You need to register a URL for the Passport server somewhere, and it is not document (or wasn't, I've raised a Pull Request). You need the following to be covered in
'laravelpassport' => [ // These are the usual Socialite/OAuth settings 'client_id' => env('LARAVELPASSPORT_CLIENT_ID'), 'client_secret' => env('LARAVELPASSPORT_CLIENT_SECRET'), 'redirect' => env('LARAVELPASSPORT_REDIRECT_URI'), // And this is how you tell Socialite where your Passport app lives 'host' => env('LARAVELPASSPORT_HOST'), ],
And that's it. You should now be able to authenticate one Laravel App against another one, and get back basic user details by return.