Laravel's 5.3 Passport and API Routes

Laravel's 5.3 passport and api routes

The problem with Laravel 5.3 passport is that unlike previous OAuth 2.0 Server for Laravel library offered by lucadegasperi, it has no API to make clients directly. So as if now the client can only be made through the front-end. FYI we wanted to use laravel passport solely for our mobile app so while creating and registering user we would have only EMAIL & Password and in some cases only Facebook UserID for facebook sign-in. So the following approach worked pretty well for our case and might differ for your scenario but may help you in the longer term to play around with laravel passport.

Note: Before following the below its assumed you have enabled Password Grant in your application.

So the way we solved it for our project on laravel 5.3 is as follows:

  1. in the oauth_clients convert the id field into a normal field i.e. remove it as being primary key and make the data type as varchar so that we can store email address as client_ids as they are also unique for your system. Incase of Facebook login we store Facebook user IDs here in this column which again will be unique for each our client. Also for other tables like: oauth_access_tokens, oauth_auth_codes & oauth_personal_access_clients change client_id to VARCHAR(255) so that it can store email addresses or Facebook User IDs.

  2. Now go to your models and create a model for oauth_clients table so that you can create client programmatically from the code while creating users.

    <?php
    namespace App;

    use Illuminate\Database\Eloquent\Model;

    class OauthClient extends Model
    {
    protected $table = 'oauth_clients';
    }
  3. Then in your api.php route file add the following route:

    Route::post('/register-user', function (Request $request) {

    $name = $request->input('name');
    $email = $request->input('email'),
    $password = $request->input('password'),

    // save new user
    $user = \App\User::create([
    'name' => $name,
    'email' => $email,
    'password' => bcrypt($password),
    ]);

    // create oauth client
    $oauth_client = \App\OauthClient::create([
    'user_id' => $user->id,
    'id' => $email,
    'name' => $name,
    'secret' => base64_encode(hash_hmac('sha256',$password, 'secret', true)),
    'password_client' => 1,
    'personal_access_client' => 0,
    'redirect' => '',
    'revoked' => 0,
    ]);

    return [
    'message' => 'user successfully created.'
    ];
    });

In the above code snippet, you have to note that to generate the oauth_client secret you have to use some strong formula of encryption that you feel comfortable using it with your application. Also, use the same technique to generate the secret key on your mobile app for the respective client/user.


  1. Now you can use the standard POST API offered by laravel passport to request access token through password grant using "oauth/token" using the following parameters:

    grant_type : 'password'
    client_id : '<email with which the user is registered>'
    client_secret : '<generate the client secret from the mobile app>'
    username : '<email with which the user is registered>'
    password : '<password entered by the user>'
    scope : '<leave empty as default>'
  2. The above will give you a response, if everything is correct, similar to :

    {
    "token_type": "Bearer",
    "expires_in": 3155673600,
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjMwZmM0MDk1NWY5YjUwNDViOTUzNDlmZjc2M2ExNDUxOTAxZjc5YTA5YjE4OWM1MjEzOTJlZmNiMDgwOWQzMzQwM2ExZWI4ZmMyODQ1MTE3In0.eyJhdWQiOiJzaHVqYWhtQGdtYWlsLmNvbSIsImp0aSI6IjMwZmM0MDk1NWY5YjUwNDViOTUzNDlmZjc2M2ExNDUxOTAxZjc5YTA5YjE4OWM1MjEzOTJlZmNiMDgwOWQzMzQwM2ExZWI4ZmMyODQ1MTE3IiwiaWF0IjoxNDc4MTQ1NjMyLCJuYmYiOjE0NzgxNDU2MzIsImV4cCI6NDYzMzgxOTIzMiwic3ViIjoiMSIsInNjb3BlcyI6W119.dj3g9b2AdPCK-im5uab-01SP71S7AR96R0FQTKKoaZV7M5ID1pSXDlmZw96o5Bd_Xsy0nUqFsPNRQsLvYaOuHZsP8v9mOVirBXLIBvPcBc6lDRdNXvRidNqeh4JHhJu9a5VzNlJPm3joBYSco4wYzNHs2BPSxXuuD3o63nKRHhuUHB-HwjVxj2GDwzEYXdZmf2ZXOGRJ99DlWGDvWx8xQgMQtd1E9Xk_Rs6Iu8tycjBpKBaC24AKxMI6T8DpelnFmUbMcz-pRsgCWCF_hxv6FpXav3jr1CLhhT58_udBvXjQAXEbtHeB7W_oaMcaqezHdAeOWDcnqREZHsnXHtKt0JpymcTWBkS2cg7sJzy6P9mOGgQ8B4gb8wt44_kHTeWnokk4yPFRZojkHLVZb8YL6hZxLlzgV1jCHUxXoHNe1VKlHArdlV8LAts9pqARZkyBRfwQ8oiTL-2m16FQ_qGg-9vI0Suv7d6_W126afI3LxqDBi8AyqpQzZX1FWmuJLV0QiNM0nzTyokzz7w1ilJP2PxIeUzMRlVaJyA395zq2HjbFEenCkd7bAmTGrgEkyWM6XEq1P7qIC_Ne_pLNAV6DLXUpg9bUWEHhHPXIDYKHS-c3N9fPDt8UVvGI8n0rPMieTN92NsYZ_6OqLNpcm6TrhMNZ9eg5EC0IPySrrv62jE",
    "refresh_token": "BbwRuDnVfm7tRQk7qSYByFbQKK+shYPDinYA9+q5c/ovIE1xETyWitvq6PU8AHnI5FWb06Nl2BVoBwCHCUmFaeRXQQgYY/i5vIDEQ/TJYFLVPRHDc7CKILF0kMakWKDk7wJdl5J6k5mN38th4pAAZOubiRoZ+2npLC7OSZd5Mq8LCBayzqtyy/QA5MY9ywCgb1PErzrGQhzB3mNhKj7U51ZnYT3nS5nCH7iJkCjaKvd/Hwsx2M6pXnpY45xlDVeTOjZxxaOF/e0+VT2FP2+TZMDRfrSMLBEkpbyX0M/VxunriRJPXTUvl3PW0sVOEa3J7+fbce0XWAKz7PNs3+hcdzD2Av2VHYF7/bJwcDCO77ky0G4JlHjqC0HnnGP2UWI5qR+tCSBga7+M1P3ESjcTCV6G6H+7f8SOSv9FECcJ8J5WUrU+EHrZ95bDtPc9scE4P3OEQaYchlC9GHk2ZoGo5oMJI6YACuRfbGQJNBjdjxvLIrAMrB6DNGDMbH6UZodkpZgQjGVuoCWgFEfLqegHbp34CjwL5ZFJGohV+E87KxedXE6aEseywyjmGLGZwAekjsjNwuxqD2QMb05sg9VkiUPMsvn45K9iCLS5clEKOTwkd+JuWw2IU80pA24aXN64RvOJX5VKMN6CPluJVLdjHeFL55SB7nlDjp15WhoMU1A="
    }

Its only a temporary solution till laravel supports an external API for applications which only has a mobile as the only possible interface for creating oAuth clients and user.

Hope it helps you!
Cheers.

404 - Not Found Passport Api Route That Exists Laravel 8

I was stuck with this for a week. There can be many things that can cause this issue.

1 - Make sure you installed passport correctly.

It appears laravel 8 comes with "Sanctum" pre-installed so there is a likelihood that you will make mistakes with some of passport's installation requirements. Go through the installation again. Passport Installation Look at the example I have below of a possible mistake.

Sample Image

Look inside your User Model and make sure you have "use Laravel\Passport\HasApiTokens;" NOT "use Laravel\Sanctum\HasApiTokens;"

Sample Image

2- If you are not using "Sanctum", you are better off removing it from your project

Go to the search on the left side bar of VSCODE and search for "Sanctum".

Sample Image

Click on "composer.json", go to the require section and carefully remove "Sanctum" requirement. Also check all the other search results to make sure you are not using Sanctum in a place where it should be passport. Remove them if need be.

Sample Image

3- In your terminal, type the command below to Update composer and generate a new lock file

composer update

4- If you moved your User model to a new folder (eg: version1) like I did, go to "config/auth.php" and update the providers for user with the correct path of the User model

Sample Image

5- Make sure in the api section of app/Http/Kernel.php, "\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class" is commented out.

Sample Image

6- Go to terminal, clear your routes from cache, list them with the commands below and check if the route you listed in api.php shows there.

php artisan route:clear

php artisan route:list

If "php artisan route:list" shows an error, then make sure your route is declared correctly. For clarity sake, make sure you use the full path of your controller and crosscheck your UserController to make sure of the function matches(they are case sensitive) exactly with what is in your api.php file. Also, if you are using a controller in your route, declare it above "use App\Http\Controllers\version1\UserController;" like shown in the image below. Repeat "php artisan route:clear" and "php artisan route:list" in terminal to make sure there is no error and your route is listed.

Sample Image

7- Make sure the url you are calling in postman is correct and the method is also correct.

Remember, if your url in api.php is "/v1/user/register" then in postman, you should have "api/v1/user/register" in postman. That means your final url will be "http://myvhostname.local/api/v1/user/register"

Remember, if you declared your route in api.php to be a "get" then make sure it is a "get" in postman. If it's a post, make sure they match in postman too.

Go to the "headers" section of postman and include "Accept=application/json" as shown below

Sample Image

8- If you still have a 404-Not Found, open your vhost file "httpd-vhosts.conf" in "Applications >> XAMPP >> xamppfiles >> etc >> extra" and make sure your vhost is declared correctly as below. Improper declaration can make web routes work but api routes won't. Pay close to "Allowoverride All".

Sample Image

Your routes should work now. If this worked for you, an upvote would be appreciated



Related Topics



Leave a reply



Submit