Choosing a provider for your API authentication can be a tricky spot. Which one should we take? Passport? Maybe JWT? Or wait, what about Sanctum? Oh and don’t forget API tokens! Ahh! So which one You should take? Let’s find out what they provide, what they are used for, and why one could fit your needs better than another.
A fair warning to those who read this article: Security has to be maintained on your end too. While packages are great at providing the logic and start – misconfiguration could lead to security breaches or even worse – hacking. So please, take a moment to read through the documentation of the chosen package. This article is not a full guide on how to set it up. It’s about helping you make a choice.
What to choose? A tl;dr; version:
This is a tl;dr; version of the article where I narrowed down the common use cases and possible expansions of the application. I am aware that there are more cases but going deeper – it requires a deeper knowledge of the differences, pros, and cons of a method. If you are interested in deeper things – read down below. If not – make use of the following list. You should be fine and have a working application with API authentication in no time!
- If you are serving a SPA from the Laravel blade file and you have a desire to open it for 3rd party support – Passport with oAuth2 is your choice. Otherwise, without the 3rd party API support, you should choose Sanctum with SPA Authentication for an easier option.
- Going to have a SPA and nothing else?
- If you are planning to have mobile apps with login:
- If you are building a SPA which can branch out into a login service (oAuth), applications, personal API access tokens, and mobile API tokens – Passport.
- Anything else – unfortunately, requires research on what is best for your case. Please take the time to check each option and make an opinion yourself.
- One time authentication for a secure application that can store your token without user access? You may use JWT. Be aware of its limitations as JWT can stay alive for a long time.
That would be it. Choosing one package over another may seem hard as most of them offer similar choices and workflows but keep in mind that initial launch is simple and the rest comes later. As an example – generating simple user tokens for authentication is easy with all of the choices but when you need to add mobile app support or even a 3rd party service – things will get messy. Take some time and evaluate each choice to see which one indeed fits your needs now and in the future.
Differences between JWT, Token, and oAuth
What is JWT?
JWT stands for JSON Web Token and is commonly used for authentication or passing data from the server to a client. This token was created as a way to pass the data from API to a client with a possible private signature.
Common use cases include passing data (not just API authentication token!) to the client that has a secret signature part. The payload assigned to a JWT can vary depending on project needs but commonly includes either a user session or something along those lines.
- Signed data can be passed via JWT token
- Quite easy to use as it’s a straight-forward approach for encoding the token. A great example is here: https://jwt.io/introduction/ at the Signature section.
Biggest issues are these:
- Tokens can be decrypted if no private signature used. To play around with encryption/decryption visit this website: https://www.jsonwebtoken.io/ and change around the Signing Key.
- The content of the token (payload) is limited as the JWT is meant to be as compact as possible.
- There’s no way to forget JWT token unless you are tracking them in the database or they expire. This means that if you granted user admin rights and removed them – they will have them until the token expires or you explicitly check the token with your database.
You can read more over here: https://jwt.io/introduction/
What is API Token?
API tokens are often confused with JWT tokens. While JWT token has a payload that can be transferred – API tokens are only for API authentication and nothing else. This means that a token is unique for the user and as long as the user passes you the token – we know that it’s him. This is done by tracking which user has which token in the database level.
- Tokens are very easy to implement. Especially if simple control is needed.
- Tokens are lightweight for those cases when data saving is needed.
- You can revoke a token instantly. This means that as soon as you tell that X token is not valid – it will result in an invalid session for the user.
- They can be easily generated/removed/updated and associated with users, their applications, browsers, phones, and anything else you may need.
- Tokens can have a different refresh token so that they wouldn’t expire.
- These tokens are not signed nor encoded.
- If listed publicly – anyone with the token and API endpoint – will access that data. Unless of course, you ensure proper CORS support and validation of the request itself.
To read more about tokens go here: https://www.oauth.com/oauth2-servers/access-tokens/
What is oAuth?
OAuth is a totally different source for our tokens with a different mindset behind it. OAuth was designed to ease off the separation of the Resource owner (user), authorization server, and Resource server logics. This means that the Resource owner is stored in one server where he is registered and authenticated. The authorization server then serves as a middleman to tie Resource owner with the Resource Server. This was a very abstract description of what oAuth is but I generally like to think that oAuth is just granting permission to application A on the API of application Z. May sound complex and honestly – it’s not too easy. Out of all 3 methods – this one is the hardest to implement and usually requires a very specific workflow.
- Great engine to authorize the usage of your application based on your users in another application. An example could be payment providers where you are the payment provider and another app authorizes your API to use a specific user’s account.
- Has great control of clients, authorization times
- Allows 3rd party clients to connect to your API.
- Gives great control of what data you return on authentication by using scopes.
- Not really suited for SPA applications. Unless you are using token-based but that is a different story.
- Really hard to get it going for the first time
- For development – it usually requires a public domain for redirects.
To read more, please visit this link: It has a more detailed explanation of how OAuth works along with schema: https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2
Sanctum and Passport comparison
What is Sanctum and what can it do?
Sanctum is a first-party package created for Laravel that is directly tinkered to be a SPA authentication provider. This, of course, does not limit it’s usage to that one thing but greatly helps with development. In my experience – Sanctum is almost as quick as session authentication. This was an intentional decision made by the framework creators and it is one of the best things that could’ve happened. It is very easy to set up and will get you going in almost no time. So rapid prototyping and development are really easy with this package.
Sanctum – SPA Authentication
The authentication setup is quite simple if your SPA is located in the same domain as your API. All you need there is a CSRF call to the API and it will handle the authentication for you. No more need to actually manage tokens and assign them anything. Laravel sessions handle that for you in the easiest way possible and you don’t have to bend your head around it. To learn how to set it up visit the documentation here: https://laravel.com/docs/7.x/sanctum#spa-authentication
Sanctum -API Authentication
It is done using simple web tokens and managing them on the API side. This means that it’s expiration, device, and authorization are managed on the API itself. No hassle to manage them on the client. This was inspired by Github API where they have tokens that are created on the Github application but can be used by the token owner anywhere. A very elegant solution to allow 3rd party clients to connect to your API. Usage is very simple as you just pass the token via Bearer token and rest is up to the API. If you’ll need to have not just a token but username and password check – read about Mobile Application Authentication Read more about the implementation here: https://laravel.com/docs/7.x/sanctum#api-token-authentication
Sanctum -Mobile application authentication
For mobile authentication users will have to send you their username/password + device name. The device name can be hard-coded in your application and upon registration – you may generate tokens for users to use automatically. This solves a huge headache when dealing with a mobile application as storing their data isn’t secure at all (remember, other apps may access storage too!). What I found interesting here is that mobile authentication doesn’t add too much complexity at all and works like a charm without any big issues. As a bonus – I’ve even used this method to authorize different Clients for API authentication where users are registered in my app and I give them access tokens with names (almost like API authentication but they have to send username/password too if they want to exchange that for a token). To read more – visit this link: https://laravel.com/docs/7.x/sanctum#mobile-application-authentication
What is Passport and what can it do?
This package offers a great way to manage multiple API authentication engines with an all-in-one package. As a result – you don’t have to worry about the requirement change. You’ll be ready. From granting simple tokens for user authentication to oAuth2 integrations. This means that you can start with a simple engine albeit harder to implement but eventually as you grow – you just add more support that is right there. There’s a jump from access tokens or grants to oAuth engine but they can work along with each other. There’s no need to rewrite what you already have if you are seeing that it’s something that your future application will use. In my opinion – this is great for projects that are growing and adding more and more things, such as mobile applications or 3rd party pages.
Passport Access tokens
Access tokens in this package are using the oAuth2 authentication engine to authorize the client within your application. This method is most commonly used for 3rd party clients that need to access your API. A great example could be Facebook, Linkedin API’s where you need to authenticate on Facebook in order to gain a token that gives you access to their API data. This method is not really meant to be used in SPA applications and could cause weird workflows. For example, your user would need to authorize your client to use your API… Makes no sense for SPA, right? To learn more about oAuth2 and how it is implemented – visit https://laravel.com/docs/7.x/passport#issuing-access-tokens
Passport Authorization with PKCE
This authorization method is quite unique due to the fact that it uses a “Code challenge” and a “Code verifier”. This comes from the fact that PKCE stands for “Proof Key for Code Exchange”. It may sound complex and too hard at first but in fact – this is a very good option in case you don’t have the ability to securely store client secret key. To get more details about implementation – visit https://laravel.com/docs/7.x/passport#code-grant-pkce
Passport Password grant tokens
Password grant tokens in my opinion are the simplest way to exchange secret key + username/password for a unique client token that acts as an authentication signature. In quite a short review all you would need to do is pass a specific client/device key along with username/password to the endpoint and you will get a token back. Of course, it will have to be refreshed once in a while and managed on your side securely but overall it’s a nice method. To read more – visit https://laravel.com/docs/7.x/passport#creating-a-password-grant-client
Passport personal access tokens
Personal access tokens are meant to be used by your user to access your API in a specific way. They would exchange a client ID along with a client secret to gain access to the API. This means that the user is in control of the token keys and can use it as they wish. This is not for your own application to be authenticated but rather for your users to get access to your API in an elegant way. It works similarly to oAuth2 except there are no redirection workflows and tokens can be added/removed at any time. In my opinion, it is a nice option to give access to API like Github, Stripe does. To read more about personal access tokens – visit https://laravel.com/docs/7.x/passport#personal-access-tokens
So what is the best method?
For the majority of SPA projects – Sanctum will be the best choice. It gives you flexibility + easy start with its session support. In this way, you won’t spend a lot of time managing sessions, tokens, or anything like that. This means – better deliverability for the client and fewer development expenses initially. On top of that – it’s quite easy to change the driver and adapt so you have room to grow. Of course, you may have some different requirements or they could change over time but you can quite easily change the authentication engine. There’s going to be some work involved but you can do the changes without tying yourself to only one way. We’ve done that in the past and in some cases we even used multiple providers/methods to authenticate our users.
When reading on this topic you may encounter a lot of suggestions for different types and this may get you overwhelmed. Of course, this comes as a problem since there are many providers and ways to do the same thing. But don’t get overwhelmed and do your own research to see what fits you. There’s no wrong choice with popular packages/providers. Why? Well, because they are a standard for specific cases. If they match yours – that’s awesome. If they don’t – look for another package. You’ll definitely find something that is worth your time. In my experience – most of them will either work out of the box or you’ll have to make minor modifications to get things going.
As always, feel free to make comments if you don’t agree with something. I’ll be more than happy to do more research on the case and update the article!