Laravel Passport vs Sanctum - How to Chose the Right Solution
If you're building an API using Laravel, you have probably stumbled over the two first-party packages offering authentication out of the box - Laravel Passport and Laravel Sanctum - and wondered which one you should pick for your project.
There is an official decision guide in the docs, but it's rather short and technical: "If your application absolutely needs to support OAuth2, then you should use Laravel Passport. However, if you are attempting to authenticate a single-page application, mobile application, or issue API tokens, you should use Laravel Sanctum."
If you've been researching this topic you will have seen this text snippet or reworded versions all over the place. But if you don't know whether or not you need OAuth2, this isn't very helpful. Which is why this blog post talks about how you can figure out if you do need Passport or can get away with using Sanctum.
But before we start, let's take a quick look at the problem both those packages try to solve.
Why do we need Authentication?
The API you are building will provide data to different clients. Unless you want to freely let anybody request any data any time they want to, you'll need to limit access somehow. That way you can ensure people's personal information isn't accessed by others, or you can bill clients for their API use, etc.
But of course the person using an app shouldn't have to enter their login information for every single request - the average app makes dozens or more calls to keep data up to date. But we also don't want to store the user's login information in the app for them to use automatically.
So we need a way for the app to be authorized by the user once and then being able to automatically authorize itself with your API for any future calls directly, without having to bother the user again and without using their login credentials.
This is achieved by using tokens - your API issues a token to a user-authorized app which it sends along on any following request, showing that it's allowed to access the requested data. This process of issuing and checking the access tokens is what both Sanctum and Passport implement for you.
The Technical Difference
So both packages aim to solve the same problem, but they do so using different technologies - which brings us back to the quote in the beginning. OAuth2 is an authorization framework for token based authentication used all other the internet. I won't go into too much detail here, but if you want to build web apps it's definitely something you should consider adding to your tool belt.
Laravel Passport implements this complex server standard, which is designed for providing specific authorization flows for web applications, desktop applications, mobile phones, and many more devices. In other words: if a thing on the internet needs to talk to another thing, there's a good chance they will use something defined in OAuth2 to communicate.
If you've ever logged into any site using Google or Facebook, then you used OAuth2. If you've paid for a SaaS tool that uses Stripe as a provider, you've used OAuth2. You get the idea.
Now, OAuth2 already simplifies authentication by defining certain standards and methods. But Laravel has a habit of trying to make things even more simple for developers, and that's where Laravel Sanctum comes into play.
Instead of all the options and methods that can be used with OAuth2, it only offers simple API tokens which can be used for internal applications that don't need to access more than a single user's data.
When it comes to working with single page applications (e.g. a VueJS app), it gets even better. Here you don't need tokens at all anymore, as Laravel Sanctum allows your API and SPA to share a session cookies as long as they are hosted on the same root domain. So you could run your API an api.tool.io and your app on app.tool.io and they can share their cookies.
Getting authentication done for an app has never been this painless.
The Practical Difference
Okay, enough talk about OAuth2 - which of the two packages should you pick?
For starters: when in doubt, pick Passport. There is nothing that Sanctum can do that's not possible with Passport as well, so if you're unsure about your needs, Passport is a safe bet.
Beyond that it comes down to figuring out whether the options offered by Sanctum are sufficient for your needs so you don't need the extra overhead Passport's more complex implementation brings along.
So let's look at some common scenarios and see which ones work with Sanctum:
your own single page application on the same domain can definitely use Sanctum, that's exactly the use case it was created for
your SPA on other domain or a mobile or mac app, or generally any app tied to a single user and created by you can use Sanctum's API tokens - since you as the developer you can simply set that up
any app or tool that needs to consume data not just linked to one user cannot use API tokens, as those are generally bound to a single user
any third party app that you do not control will have to use whatever authentication method the developers implemented - if they don't allow for API tokens, you will need other methods using Passport
So to summarize the decision in one sentence: if you own all the clients and they only consume user specific data, you're probably good with Sanctum, otherwise there is a good chance you need Passport.
Switching Packages in the Future
What if I choose one package now and then realize in a year or two that I made the wrong call? Can I simply switch from one to the other or will I have to rewrite half my app?
If you already have Passport set up, there is probably no reason to revert to Sanctum. However if you've built your SPA using Sanctum and later want to also integrate thirds party services, you might suddenly need Passport to implement OAuth2.
Thanks to Laravel's abstraction the changes to the code are minimal, change a few lines in your classes and route file and you're done. Of course you will also have to implement the actual authentication workflow, just as you would setting up Passport from the start.
The only downside besides a bit of work is that sessions cannot be transferred from one system to the other. So when you change your authentication method, all users and apps will be logged out and have to authenticate again. Not a big deal for users, but might be a headache for any systems that automatically pull data from your API for their own work.
So make sure to warn and inform your users to give them time to prepare.
Final Thoughts
For the app I'm currently building I've decided to go with Sanctum, simply because it's easier and faster to set up and I don't need OAuth2 for the functionality I have currently planned in the beginning.
It's easy to over engineer everything in development without ever getting a single paying client, something I'm trying to avoid these days. If this app ever does go beyond the prototype stage and I want to add third party integrations at some time, I will definitely let you know how switching to Passport went.