Install and Configure Laravel with Passport
First we install and configure laravel app with passport then next we install the open api l5 swagger for api documentations.
Step 1: Install Laravel App
First create a new Laravel application using the following mentioned command.
1 |
composer create-project --prefer-dist laravel/laravel blog |
Step your database credentials in your env file.
1 2 3 4 5 6 |
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=laravel9 DB_USERNAME=root DB_PASSWORD= |
Step 3: Install Laravel Passport
Install Laravel Passport using composer just run the below command.
1 |
composer require laravel/passport |
Step 4: Migrate your Database
Run the following command to migrate your database.
1 |
php artisan migrate |
Step 5: Install Passport
Next, to create the encryption keys needed to generate secured access tokens and save at secure place, run the command below
1 |
php artisan passport:install |
Step 6: Update User Model
After the installation process, add the Laravel\Passport\HasApiTokens trait to your App\User model as shown here
1 2 3 4 5 6 7 8 9 10 |
// app/User.php <?php namespace App; ... use Laravel\Passport\HasApiTokens; // include this class User extends Authenticatable { use Notifiable, HasApiTokens; // update this line ... } |
Step 7: Update Code in Service provider
Note: if you face error like: Call to undefined method Laravel\Passport\Passport::routes()
then simply skip this step
open the AuthServiceProvider file and update code just like below.
app/Providers/AuthServiceProvider.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<?php namespace App\Providers; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; use Illuminate\Support\Facades\Gate; use Laravel\Passport\Passport; // add this class AuthServiceProvider extends ServiceProvider { /** * The policy mappings for the application. * * @var array */ protected $policies = [ 'App\Model' => 'App\Policies\ModelPolicy', // uncomment this line ]; /** * Register any authentication / authorization services. * * @return void */ public function boot() { $this->registerPolicies(); Passport::routes(); // Add this } } |
Step 8: Set the Driver Option
To authenticate any incoming API requests, open the config/auth configuration file and set the driver option of the API authentication guard to passport just like below code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// config/auth <?php return [ ... 'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'passport', // set this to passport 'provider' => 'users', 'hash' => false, ], ], ... ]; |
The laravel passport configuration is completed, Now we install and configure the Swagger for generating laravel documentations.
Integration of Swagger in Laravel Application
Now here step by step to install and configure the swagger api for laravel documentations.
Step 1: Install Swagger open Api
Now install the Swagger according to the Laravel version that you have installed. For more information visit DarkaOnLine/L5-Swagger
1 |
composer require "darkaonline/l5-swagger" |
Step 2: Publish Swagger’s configuration
You can publish Swagger’s configuration and view files into your project by running the following command.
1 |
php artisan vendor:publish --provider "L5Swagger\L5SwaggerServiceProvider" |
Step 3: Enable passport authentication
Enable passport authentication we need to uncomment Open API 3.0 support in security array of config/l5-swagger.php file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
'security' => [ // Open API 3.0 support 'passport' => [ // Unique name of security 'type' => 'oauth2', // The type of the security scheme. Valid values are "basic", "apiKey" or "oauth2". 'description' => 'Laravel passport oauth2 security.', 'in' => 'header', 'scheme' => 'https', 'flows' => [ "password" => [ "authorizationUrl" => config('app.url') . '/oauth/authorize', "tokenUrl" => config('app.url') . '/oauth/token', "refreshUrl" => config('app.url') . '/token/refresh', "scopes" => [] ], ], ], ], |
Step 4: Update Routes
Now, we need to create routes for API just update the below routes.
routes\api.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?php use Illuminate\Http\Request; use App\Http\Controllers\Api\AuthController; /* |-------------------------------------------------------------------------- | API Routes |-------------------------------------------------------------------------- | | Here is where you can register API routes for your application. These | routes are loaded by the RouteServiceProvider within a group which | is assigned the "api" middleware group. Enjoy building your API! | */ Route::post('login', [AuthController::class,'login']); Route::post('register', [AuthController::class,'register']); Route::middleware('auth:api')->get('/user', function (Request $request) { return $request->user(); }); |
Step 5: Create Controller
Now create a new controller AuthController using the following the command.
1 |
php artisan make:controller Api/AuthController |
After genrating the controller update the below code on it.
app\Http\Controllers\Api\AuthController.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
<?php namespace App\Http\Controllers\Api; use Illuminate\Http\Request; use App\Http\Controllers\Controller; use Hash; use App\User; class AuthController extends Controller { /** * @OA\Post( * path="/api/register", * operationId="Register", * tags={"Register"}, * summary="User Register", * description="User Register here", * @OA\RequestBody( * @OA\JsonContent(), * @OA\MediaType( * mediaType="multipart/form-data", * @OA\Schema( * type="object", * required={"name","email", "password", "password_confirmation"}, * @OA\Property(property="name", type="text"), * @OA\Property(property="email", type="text"), * @OA\Property(property="password", type="password"), * @OA\Property(property="password_confirmation", type="password") * ), * ), * ), * @OA\Response( * response=201, * description="Register Successfully", * @OA\JsonContent() * ), * @OA\Response( * response=200, * description="Register Successfully", * @OA\JsonContent() * ), * @OA\Response( * response=422, * description="Unprocessable Entity", * @OA\JsonContent() * ), * @OA\Response(response=400, description="Bad request"), * @OA\Response(response=404, description="Resource Not Found"), * ) */ public function register(Request $request) { $validated = $request->validate([ 'name' => 'required', 'email' => 'required|email|unique:users', 'password' => 'required|confirmed', 'mobile_number' => 'required', ]); $data = $request->all(); $data['password'] = Hash::make($data['password']); $user = User::create($data); $success['token'] = $user->createToken('authToken')->accessToken; $success['name'] = $user->name; return response()->json(['success' => $success]); } /** * @OA\Post( * path="/api/login", * operationId="authLogin", * tags={"Login"}, * summary="User Login", * description="Login User Here", * @OA\RequestBody( * @OA\JsonContent(), * @OA\MediaType( * mediaType="multipart/form-data", * @OA\Schema( * type="object", * required={"email", "password"}, * @OA\Property(property="email", type="email"), * @OA\Property(property="password", type="password") * ), * ), * ), * @OA\Response( * response=201, * description="Login Successfully", * @OA\JsonContent() * ), * @OA\Response( * response=200, * description="Login Successfully", * @OA\JsonContent() * ), * @OA\Response( * response=422, * description="Unprocessable Entity", * @OA\JsonContent() * ), * @OA\Response(response=400, description="Bad request"), * @OA\Response(response=404, description="Resource Not Found"), * ) */ public function login(Request $request) { $validator = $request->validate([ 'email' => 'email|required', 'password' => 'required' ]); if (!auth()->attempt($validator)) { return response()->json(['error' => 'Unauthorised'], 401); } else { $success['token'] = auth()->user()->createToken('authToken')->accessToken; $success['user'] = auth()->user(); return response()->json(['success' => $success])->setStatusCode(200); } } } |
Step 6: Generate Swagger
To generate the swagger documentation file just run php artisan l5-swagger: generate command.
1 |
php artisan l5-swagger:generate |
More then times when you generate the swagger It will return an error
1 |
Required @OA\Info() not found |
That means that you have to create that notation first. So let’s add it. I prefer creating Abstract controller for an API, but you can add this to app/Http/Controllers/Controller.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?php namespace App\Http\Controllers; use Illuminate\Foundation\Bus\DispatchesJobs; use Illuminate\Routing\Controller as BaseController; use Illuminate\Foundation\Validation\ValidatesRequests; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; /** * @OA\Info( * title="Your super ApplicationAPI", * version="1.0.0", * ) */ class Controller extends BaseController { use AuthorizesRequests, DispatchesJobs, ValidatesRequests; } |
Step 7: Open the Documentation
1 |
http://laravel-project.co/api/documentation |
Note: we are using body parameter for creating api documentation in laravel with swagger open api. If you want to add query paramter then add some like below code.
Api Docuentation using Query Parameters
Below code for user register..
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
/** * @OA\Post( ** path="/api/user-register", * tags={"Register"}, * summary="Register", * operationId="register", * * @OA\Parameter( * name="name", * in="query", * required=true, * @OA\Schema( * type="string" * ) * ), * @OA\Parameter( * name="email", * in="query", * required=true, * @OA\Schema( * type="string" * ) * ), * @OA\Parameter( * name="mobile_number", * in="query", * required=true, * @OA\Schema( * type="integer" * ) * ), * @OA\Parameter( * name="password", * in="query", * required=true, * @OA\Schema( * type="string" * ) * ), * @OA\Parameter( * name="password_confirmation", * in="query", * required=true, * @OA\Schema( * type="string" * ) * ), * @OA\Response( * response=201, * description="Success", * @OA\MediaType( * mediaType="application/json", * ) * ), * @OA\Response( * response=401, * description="Unauthenticated" * ), * @OA\Response( * response=400, * description="Bad Request" * ), * @OA\Response( * response=404, * description="not found" * ), * @OA\Response( * response=403, * description="Forbidden" * ) *) **/ |
More examples of different @OA\Property types
- If You want to upload files (image, for zip, csv file) just update like below
1 |
* @OA\Property(property="current_cv", type="file"), |
2. You can use predefined format=” email” and even regexp pattern.
1 |
* @OA\Property(property="email", type="string", pattern="^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$", format="email", example="[email protected]"), |
3. You can use type=” array” and collectionFormat=” multi” to describe an array of validation errors. You need to define @OA\Items annotation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
* @OA\Response( * response=422, * description="Validation error", * @OA\JsonContent( * @OA\Property(property="message", type="string", example="The given data was invalid."), * @OA\Property( * property="errors", * type="object", * @OA\Property( * property="email", * type="array", * collectionFormat="multi", * @OA\Items( * type="string", * example={"The email field is required.","The email must be a valid email address."}, * ) * ) * ) * ) * ) |
4. When you need to describe an array of objects you can use type=” array” and pass object via @OA\Items
1 |
@OA\Property(property="data", type="array", @OA\Items(ref="#/components/schemas/City")) |
Code for when parameter in URL
Whenever you need to describe parameter in URL (e.g. /api/users/{userId}/details )you can use @OA\Parameter.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
/** * @OA\Get( * path="/api/users/{userId}/details", * summary="Get User Details", * description="Get User Details", * operationId="GetUserDetails", * tags={"UserDetails"}, * security={ {"bearer": {} }}, * @OA\Parameter( * description="ID of User", * in="path", * name="userId", * required=true, * example="1", * @OA\Schema( * type="integer", * format="int64" * ) * ) * ) */ |
That’s all the the Laravel API Documentation with Swagger Open Api and Passport is over now. There are more options and features of l5 swagger open api you can use.
Leave a reply