How to use Passport with Laravel Modules (nwidart)
Tags: laravel, php, discuss
Published: 2019-09-18 03:18:58

Let me introduce these two packages for those who are new to it.

**Laravel Passport:** 

> Laravel makes API authentication a breeze using Laravel Passport, which provides a full OAuth2 server implementation for your Laravel application in a matter of minutes. Passport is built on top of the [League OAuth2 server](https://github.com/thephpleague/oauth2-server) that is maintained by Andy Millington and Simon Hamp.

Note: I followed the Medium article to configure Passport - [Here is the medium article for further reference.](https://medium.com/techcompose/create-rest-api-in-laravel-with-authentication-using-passport-133a1678a876)

**Laravel Modules:**

> `nwidart/laravel-modules`  is a Laravel package which was created to manage your large Laravel app using modules. A module is like a Laravel package, it has some views, controllers or models. This package is supported and tested in Laravel 5.
> 
> This package is a re-published, re-organised and maintained version of [pingpong/modules](https://github.com/pingpong-labs/modules), which isn't maintained anymore. This package is used in  [AsgardCMS](https://asgardcms.com/).

When creating enterprise applications, it will be much useful to develop them as modular as possible to make it maintainable. I was going through a scenario where I have to implement a users module using Laravel Module and authentication is using Passport. Here is how I did it.

**1.Start a new laravel project**

    composer create-project laravel/laravel my-app

For making it less clutter, I moved the default migrations out of this project. We will later be adding it back to the project under user module.

    cd my-app

 **2. Install and configure Laravel Modules:**

    composer require nwidart/laravel-modules
    php artisan vendor:publish --provider="Nwidart\Modules\LaravelModulesServiceProvider"

 **3. Add Modules folder to autoload array in composer.json:**

    "autoload": {
            "psr-4": {
                "App\\": "app/",
                "Modules\\": "Modules/"
            },
            "classmap": [
                "database/seeds",
                "database/factories"
            ]
        },

**4. Run auto load**

    composer dumpautoload

**5. Create Users module and model:**

    php artisan module:make Users
    php artisan module:make-model User Users

**6. Copy the migration under *my-app/Modules/Users/Database/Migrations***

We will set up the login and registration functionalities once we finish configuring the Passport.

**7. Install and configure Passport:**

    composer require laravel/passport

**8. Edit config/app.php to add Passport service provider**

    'providers' =>[
    Laravel\Passport\PassportServiceProvider::class,
    ],

**9. Run migrate and install - Install will create the token keys for security.**

    php artisan migrate
    php artisan passport:install

**10. Move the app/User.php to Modules/Users/Entities/User.php**

**11. app/Providers/AuthServiceProvider.php**

    <?php
    namespace App\Providers;
    use Laravel\Passport\Passport; 
    use Illuminate\Support\Facades\Gate; 
    use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
    class AuthServiceProvider extends ServiceProvider 
    { 
        /** 
         * The policy mappings for the application. 
         * 
         * @var array 
         */ 
        protected $policies = [ 
            'App\Model' => 'App\Policies\ModelPolicy', 
        ];
    /** 
         * Register any authentication / authorization services. 
         * 
         * @return void 
         */ 
        public function boot() 
        { 
            $this->registerPolicies(); 
            Passport::routes(); 
        } 
    }

**12. IMPORTANT**: In config/auth.php, specify the api authentication driver to passport. Also, in providers, let laravel know that we have to use the User class inside Modules to be the model. **NOT** the default app/User::class.

    <?php
    return ['guards' => [   
        'web' => [   
            'driver' => 'session',   
            'provider' => 'users',   
        ],   
        'api' => [   
            'driver' => 'passport',   
            'provider' => 'users',   
        ],   
    ],
    .
    .
    .
    'providers' => [
            'users' => [
                'driver' => 'eloquent',
                'model' => Modules\Users\Entities\User::class,
            ],
    
            // 'users' => [
            //     'driver' => 'database',
            //     'table' => 'users',
            // ],
        ],

**13. Add API Routes in Modules/Users/Routes/api.php**

    Route::post('login', 'UsersController@login');
    Route::post('register', 'UsersController@register');

**14. Create Users Controller - Laravel Module will create this on its own when we create the model.**

    <?php
    
    namespace Modules\Users\Http\Controllers;
    
    use Validator;
    use Illuminate\Http\Request;
    use Illuminate\Http\Response;
    use Modules\Users\Entities\User;
    use Illuminate\Routing\Controller;
    use Illuminate\Support\Facades\Auth; 
    
    class UsersController extends Controller
    {
        public $successStatus = 200;
        
        /**
        * Handles user logins
        *
        * @return void
        */
        public function login()
        {
            if(Auth::attempt(['email' => request('email'), 'password' => request('password')])){ 
                $user = Auth::user(); 
                $success['token'] =  $user->createToken('my-app')-> accessToken; 
                return response()->json(['success' => $success], $this-> successStatus); 
            } 
            else{ 
                return response()->json(['error'=>'Unauthorised'], 401); 
            } 
        }
        
        /** 
         * Register api 
         * 
         * @return \Illuminate\Http\Response 
         */ 
        public function register(Request $request) 
        { 
            $validator = Validator::make($request->all(), [ 
                    'name' => 'required', 
                    'email' => 'required|email', 
                    'password' => 'required', 
                    'c_password' => 'required|same:password', 
                ]);
                if ($validator->fails()) { 
                    return response()->json(['error'=>$validator->errors()], 401);            
                }
                $input = $request->all(); 
                $input['password'] = bcrypt($input['password']); 
                $user = User::create($input); 
                $success['token'] =  $user->createToken('MyApp')-> accessToken; 
                $success['name'] =  $user->name;
                return response()->json(['success'=>$success], $this-> successStatus); 
            }
    
            /** 
            * details api 
            * 
            * @return \Illuminate\Http\Response 
            */ 
            public function details() 
            { 
                $user = Auth::user(); 
                return response()->json(['success' => $user], $this-> successStatus); 
            } 
    
        }
    
**15.** In command line, run the server and you will be able to test it using Postman or Insomnia.

    php artisan serve

Please feel free to ask any questions on this article. I will be happy to help. Reach me - santhoshj at gmail dot com.

> 
> Written with [StackEdit](https://stackedit.io/).