Laravel 8 API authentication using Passport from the scratch
Laravel provides 2 ways API authentication using API tokens. Laravel Sanctum is useful for single page application, mobile application or small application. However it doesn't support OAuth2, so if you want your application authentication using OAuth2, Laravel Passport is the best option for Laravel 8 application.
In this tutorial article, we will set Laravel Passport authentication into Laravel 8 application. We will do it from the scratch. Below are the steps we will follow in this tutorial.
- Step 1: Create fresh Laravel application
- Step 2: Configure MySQL database
- Step 3: Install Passport package
- Step 4: Configure Passport into application
- Step 5: Create controller for authentication
- Step 6: Create authentication routes
- Step 7: Test application using Postman
So, let's start from creating new Laravel 8 application.
Step 1: Create fresh Laravel application
Of course first step is to create a fresh Laravel application. We will create application using composer command. You can install Composer with following this article. Open the Terminal or CMD and run the following command from the directory where you want to create Laravel application.
composer create-project laravel/laravel passport
After the application is created, next is to change directory using cd command.
cd passport
Step 2: Configure MySQL database
We will configure MySQL database into .env file. All issued token are stored into database. So open .env file and change the database credentials according to your MySQL.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=passport
DB_USERNAME=root
DB_PASSWORD=secret
Step 3: Install Passport package
In the third step, we will install Laravel Passport. Laravel Passport is built on top of the League OAuth2 server that is maintained by Andy Millington and Simon Hamp.
Run the below composer command to install Passport package.
composer require laravel/passport
Now run the migrate command to create tables into database. Passport's service provider also creates its own database table. So you should always migrate your database after installing this package.
php artisan migrate
Now we needed to run passport:install artisan command. This will create encryption keys needed to generate secure access tokens.
php artisan passport:install
Step 4: Configure Passport into application
After the Passport installed, next step is to configure into Laravel application. You need to add few lines into application files. First open the model which you want to use for authentication. We will use Laravel's default User model to authenticate. In the model, add Laravel\Passport\HasApiTokens
trait.
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
}
Note: User model already use Laravel\Sanctum\HasApiTokens
trait, so you need to change it to Laravel\Passport\HasApiTokens
. Or you may set alias using as
keyword.
Now, you need to add Laravel\Passport\Passport::routes()
method into the boot method of your App\Providers\AuthServiceProvider
.
<?php
namespace App\Providers;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
use Laravel\Passport\Passport;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
'App\Models\Model' => 'App\Policies\ModelPolicy',
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
if (! $this->app->routesAreCached()) {
Passport::routes();
}
}
}
Add the Passport's api guard into config/auth.php
. So, open config/auth.php
file and add api guard as below:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
Finally, run passport:keys command into Terminal to generates the encryption keys Passport needs in order to generate access tokens.
php artisan passport:keys
Step 5: Create controller for authentication
We have integrated Laravel Passport. Now we need controller to authenticate users .This will issue and use Passport tokens. Run the following artisan command to create controller class.
php artisan make:controller PassportController
This will create controller class at app/Http/Controllers/PassportController.php
file. Open the file and add below methods into it.
<?php
namespace App\Http\Controllers;
use Validator;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Laravel\Passport\TokenRepository;
use Laravel\Passport\RefreshTokenRepository;
class PassportController extends Controller
{
/**
* Register user.
*
* @return json
*/
public function register(Request $request)
{
$input = $request->only(['name', 'email', 'password']);
$validate_data = [
'name' => 'required|string|min:4',
'email' => 'required|email',
'password' => 'required|min:8',
];
$validator = Validator::make($input, $validate_data);
if ($validator->fails()) {
return response()->json([
'success' => false,
'message' => 'Please see errors parameter for all errors.',
'errors' => $validator->errors()
]);
}
$user = User::create([
'name' => $input['name'],
'email' => $input['email'],
'password' => Hash::make($input['password'])
]);
return response()->json([
'success' => true,
'message' => 'User registered succesfully, Use Login method to receive token.'
], 200);
}
/**
* Login user.
*
* @return json
*/
public function login(Request $request)
{
$input = $request->only(['email', 'password']);
$validate_data = [
'email' => 'required|email',
'password' => 'required|min:8',
];
$validator = Validator::make($input, $validate_data);
if ($validator->fails()) {
return response()->json([
'success' => false,
'message' => 'Please see errors parameter for all errors.',
'errors' => $validator->errors()
]);
}
// authentication attempt
if (auth()->attempt($input)) {
$token = auth()->user()->createToken('passport_token')->accessToken;
return response()->json([
'success' => true,
'message' => 'User login succesfully, Use token to authenticate.',
'token' => $token
], 200);
} else {
return response()->json([
'success' => false,
'message' => 'User authentication failed.'
], 401);
}
}
/**
* Access method to authenticate.
*
* @return json
*/
public function userDetail()
{
return response()->json([
'success' => true,
'message' => 'Data fetched successfully.',
'data' => auth()->user()
], 200);
}
/**
* Logout user.
*
* @return json
*/
public function logout()
{
$access_token = auth()->user()->token();
// logout from only current device
$tokenRepository = app(TokenRepository::class);
$tokenRepository->revokeAccessToken($access_token->id);
// use this method to logout from all devices
// $refreshTokenRepository = app(RefreshTokenRepository::class);
// $refreshTokenRepository->revokeRefreshTokensByAccessTokenId($$access_token->id);
return response()->json([
'success' => true,
'message' => 'User logout successfully.'
], 200);
}
}
Step 6: Create authentication routes
We have created controller class and methods. Now we need routes to handle these methods. API routes are located at routes/api.php
file. So open this file and add following routes.
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PassportController;
Route::post('register', [PassportController::class, 'register']);
Route::post('login', [PassportController::class, 'login']);
// put all api protected routes here
Route::middleware('auth:api')->group(function () {
Route::post('user-detail', [PassportController::class, 'userDetail']);
Route::post('logout', [PassportController::class, 'logout']);
});
Step 7: Test application using Postman
We have completed the application coding part. Now we need to test API. For that we will use Postman application. We will test register, login, fetch user details with authentication and logout.
First of all, start Laravel server using following artisan command.
php artisan serve
Test application
In the application, if your request data is correct, you will get success parameter with true. If there is error, success response is false along with errors parameter response all errors. All the routes in routes/api.php
are prefixed with api.
Register user
In the Postman, use http://localhost:8000/api/register
post url, with data as below screenshot. If the success parameter in response is true, that means, the user is successfully registered.
Login user
Now we need access token, which will be used to access all authentication protected routes. To get token, we use login method. In the Postman, use http://localhost:8000/api/login
url with email and password data. If the credentials is right, you will get token parameter with access token.
Get User details.
We have get the access token. Save this token to anywhere in your frontend application. In the authentication protected routes, we need to pass this token in the header.
Authorization: Bearer eqyJ0eX...............8_lZKM
If you pass wrong token or omit this header, the application response Unauthenticated message.
Logout user
When user run logout route, we revoke the token and expire it. You can logout user from the current device or from the all device. Logging out user from all devices will revoke all issued token fot that user.
Conclusion
So in this tutorial article, we have implemented API registration, login, access protected routes and logout. You can find more customization details for Passport at official documentation. I hope this tutorial will help you on building awesome application. Happy coding.
Copyright 2023 HackTheStuff