How to Implement OAuth correctly in API with Laravel Passport? How to Implement OAuth correctly in API with Laravel Passport? laravel laravel

How to Implement OAuth correctly in API with Laravel Passport?


It's going to take too long for me to answer each of your questions in depth, so I'vetried to link to the relevant sections in the RFC for further reading.

Essentially, I would recommend for you to use the password credentials grant flow for your first-party clients (your mobile app and web app). One of the clients thatLaravel would have created for you, would have been the "Laravel Password Grant Client" and itsdocumentation is available here.

You would still need to define your own "register" route, but you can use the oauth/token routeinstead of your own /login route.

  1. What is exactly Oauth server? Is it my own server that is hosted by API?

The OAuth server would be your server that is running Passport. Or in the officialterminology according to the RFC, theOAuth server/Passport server would be called the "authorization server."

In your case, the "resource server", which your API that serves your content, would bethe same server as the "authorization server."

  1. After Laravel Passport configuration and database migration, Laravel Passport created some tables in my database, I would be really appreciated if you could tell me what is the purpose of each tables? table names are failed_jobs, oauth_access_tokens, oauth_auth_codes, oauth_clients, oauth_personal_access_clients, oauth_refresh_tokens.

The failed_jobs table is not directly related to Passport. It's related to Laravel's queues. See Dealing With Failed Jobs.

The rest of the tables are all there so that Passport can keep track of the clients and codes it has created.

  • oauth_clients: See the RFC clients section.
  • oauth_access_tokens: See the RFC access tokens section.
  • oauth_auth_codes: See Authorization Code Grant.
  • oauth_personal_access_clients: Personal access clients don't seem to be part of the official specification, but it is basically a client for when a user wants to get an access token directly, instead of going through an app or website. Usually this would be a developer who wants to get an access token to be able to call API endpoints on their own account.The personal access clients table stores clients that were specifically created for this purpose. Usually there wouldonly be one of them.
  • oauth_refresh_tokens: See the RFC refresh tokens section.
  1. Is it right to create a personal access token for my two types of users? What is exactly a personal access token?

Every user would need to get their own access token, but not a personal access token.

Personal access tokens are just access tokens that were created specifically for users who wants to generateand use the access token themselves. In Laravel Passport, specifically, they are access tokenswhich are linked to the "Laravel Personal Access Client."

So in your case, your server would create "normal" access tokens for users and not "personal" accesstokens.

  1. Am I doing right to create a personal access token when teachers and students login to their account or I should do another way to handle it?! this way works, but I'm looking for correct way if there is anything else.

See answer to question 3.

  1. The weird thing here is Laravel Passport create a token every time users login and it doesn't check if they have already created token or not? If someone can access the API endpoint, they can make a post request to /login endpoint and create a lot of tokens. Is it a problem? How to fix it?

I don't think this is a problem. The oauth/token route is rate-limited. You can rate-limit it even more.

You can also listen to events and delete or revoke tokensif want to limit the amount of tokens there may be for a single user.

  1. When I create a personal access token I need to pass an argument to createToken($arg) method, and it stores in oauth_personal_access_clients table. what is the purpose of this? Is it just for Laravel Passport purpose, or maybe I need it in the future?

This table is just for Laravel Passport. It can also be of use for when you want to audit or debug something later on.

The row that you see in the oauth_personal_access_clients table, was created when you ran php artisan passport:install.

When you call createToken, a new row is inserted into oauth_access_tokens.

  1. I have some endpoints which are not protected by auth:api middleware, for example, every user visit my application they can search for teachers name and lessons and ... , it's not necessary to make them login or register first. These endpoints are accessible to everyone in my application, and they are free to search and advance search for some information. My question is if I make it accessible to everyone, how can I protect these endpoints that only my first-party app and third-party app can access them. I mean I don't want people to access them by command line or postman or some kind of these tools without access token, I want to protect these endpoints from attackers not to make a huge requests to make my server down. How can I protect this kind of endpoints? I know I can limit requests per minute, but I don't know how much limit it? Is there any other way?

Yes, you'll have to do rate-limiting. You'll have to experiment and see what works for you.

  1. I see there is a term called clients in Oauth terminology, as I understand clients are the applications like web applications or native mobile app and any other applications that use my API are called clients. Am I right? And I think this is for third-party application authentication. I'm a little bit confused after reading Laravel Passport documentation about clients, and when I configured the Laravel Passport, it generates two clients and stored them in database. Do I need to create a client for my Applications?! How Can I ignore authorization flow just for first-party applications?

Yes, clients are like web applications, mobile apps, etc. Usually you would have a newclient for every mobile app, web app, CLI, etc., but in addition to those apps, Laravel definesthe "Password Grant Client" and the "Personal Access Client" clients for you which havespecific purposes.

You can use the Laravel Password Grant Client forboth of your applications since they're first-party applications.

You can ignore the authorization flow for first-party applications by using the/oauth/token route that is provided forpassword grant clients.

The RFC section about the password credentials flow is available here.

You can read more about how the RFC defines clients here.

  1. What is the usage of these routes? do I need them to create my first-party applications?

Needed for first-party applications:

  • /oauth/token

Not needed for first-party applications:

  • /oauth/clients: this is for a third-party developer to see which clients they have created.
  • /oauth/clients/{client-id}: for a third-party developer to update one of their clients.
  • /oauth/authorize: this route will be called by a third-party developer to start theauthorization grant flow with their client ID and secret.

You can read more about the above routes under the "JSON API" section in Managing clients.

  1. As I said the future purpose of this application is to make the API accessible by third-party applications, I have to create a web page that developers register an account and get/buy a token to access my API. is it possible to do it with Laravel Passport or I should write my own logic to make it work? Do I need to create a client for my third-party clients?

Laravel Passport provides Vue components that you can use so that developers will be able to create clients. You can either use these components or you can create your own frontend and callthe JSON API routes from your own frontend.

Keep in mind that OAuth was designed originally for when third-party apps needs to access things on behalf of a user. So instead of getting access tokens, third-party apps will get a client ID and client secret and they will need to go through one of the authorization grant flows for each user that they want to act on behalf of.

If you're never going to have third-party apps that need to act on behalf of users, it might be worth considering other protocols like mentioned in the comments.