Laravel Passport authentication is really a powerful feature. It enables an authentication system with a token. On the basis of the token, it manages all the HTTP requests which are using the web services. The token identifies the user whether it is valid or not. In other words, every single request that is trying to access the data should be authentic. Without an authentic request, it will not allow you to access the data. I have already shown you how to use passport authentication in Laravel 6 RESTful APIs. Today, I am going to create RESTful APIs for the To-do application. In this application, I will manage CRUD operation through the APIs for the ToDo application. So, let’s start.
Prerequisites
Your system must be configured with the following.
- Composer
- PHP <=7.3.9
- MySQL <=5 (Recommended MySQL 8)
- A Web server (Apache, NGINX) for testing.
- VS Code Editor
Once your system has ready for creating the Laravel 6 application, let’s create a new one.
Create Laravel 6 ToDo Application
Open the terminal and create a new project. Just enter the below command there. It will start creating a new project with Laravel 6 installation.
composer create-project --prefer-dist laravel/laravel todo-app
Once, the project has been created, open it in the VS Code Editor.
How to Integrate Laravel 6 Application with Firebase
REST API ToDo Application Project Structure
I am going to create RESTful APIs for the Laravel 6 ToDo application. In this project, we’ll have the following modules.
- User
- Task
- The User can be created by signup with some basic details. (User SignUp)
- Registered users can log in to their accounts. (User Login)
- A user can have only one account with the same detail.
- After the successful login of the user, a token will be generated for the user. Using that token, the user’s other APIs will be called with the help of middleware.
- The logged-in user can create a task with details.
- The user can manage the task status like the progress of completion, completed, or pending state.
- The logged-in user can view own created task.
- The user can update the task.
- Delete the task.
Create and Configure MySQL Database
Open the MySQL command line or GUI and create a new database there.
CREATE DATABASE laravel6_todo_rest;
Here, my database name is laravel6_todo_rest
.
Now, you will need to configure the database credentials inside the project. Move to the .env file inside the project directory and change the MySQL connection with the below snippet. But don’t forget to replace DB_USERNAME
and DB_PASSWORD
with your database details.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel6_todo_rest
DB_USERNAME=root
DB_PASSWORD=root
After creating the database, we will install the Laravel Passport.
Laravel 6 Login and Registration System with Authentication
Install Laravel Passport Auth
Inside the project, you will need to install the Laravel 6 passport auth. It will add the authentication dependency in your Laravel 6 project. Basically, the passport auth adds some token-based values to maintain the unique user id authentication.
Open the terminal and type the below command to install the Laravel Passport Authentication.
composer require laravel/passport
It will take a few minutes to set up the auth in your Laravel 6 todo application. So, just wait while it completes.
Eloquent Model and Migration in Laravel 6 ToDo Application
In this project, we will require two models. Firstly, we will need a User model. The User model will be for managing the User’s account. For Laravel passport authentication, we must require users. Secondly, we will require a Task model. The Task model will contain the Task that will be created by the User. Laravel provides the User model by default with the project creation.
In Laravel, every model is related to a specific database table. So, every model has its own migration file that is related to the database table.
Firstly, we will see the User model migration that will create a table for the users.
// create_users_table.php
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
Now, move to the User.php (Model) and add the following fillable data.
// User.php
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
Secondly, we will create a model and migration for the task.
Laravel 6 RESTful APIs for Blog Application with Passport Auth
Create a Model and Migration For Task
Enter the below command in the terminal. It will create a Task model with its migration file.
php artisan make:model Task --migration
Configure create_tasks_table
Here, I have added the following fields for the Tasks table. Also, I have added reference of user_id from the id of the Users table.
public function up()
{
Schema::create('tasks', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('task_title');
$table->string('category');
$table->string('description');
$table->bigInteger('user_id')->unsigned();
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
}
Add Fillable Data in Task Model
In the next step, we’ll have to add the fillable data in the Task model. These fillable data will be saved into the tasks table.
protected $fillable = [
'task_title', 'category', 'description', 'user_id'
];
Upload Files and Images in Laravel 6 with Validation
Create Relation Between User and Task Model
In Laravel 6, the eloquent model creates simplicity for database operations. So, we need to specify the relation between the models. Rest, the Laravel model understands automatically to treat with the data.
According to our project, the user can have more than one task. So, this is one-to-many relations. Similarly, a task can be created by a single user. Also, multiple tasks can be created by a single user. Hence, this is a reverse relation.
So next, create a new method inside the User model to define the relation.
public function task()
{
return $this->hasMany('App\Task');
}
Here, hasMany() function defines the one-to-many relation in the Laravel eloquent.
Therefore, after specifying the relation, the User.php file will look like this.
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function task()
{
return $this->hasMany('App\Task');
}
}
Migrate Database in Laravel 6 ToDo Application
After the configuration of the table schemas in the migration, we will need to add these into the database. So, enter the below command to migrate the tables.
php artisan migrate
It will add all the tables in the database. Importantly, it has been added the passport auth tables also. These passport auth tables will maintain the authentication for the users.
Add Passport Auth Encryption Key
Next, we will need to add the encryption key, and client secret key inside the table. This will be added automatically by running the command.
php artisan passport:install
This command will add the “Personal access” and “Password grant” clients in the table. Which will be used for managing the access tokens.
You can check inside the oauth_personal_access_clients and oauth_clients table. There will be two values for Personal access client and Password grant client. These will manage the access tokens.
Next, you will have to add the passport routes in AuthServiceProvider.php file. After adding the routes it will become like as shown below.
// app/Providers/AuthServiceProvider.php
<?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\Model' => 'App\Policies\ModelPolicy',
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
Passport::routes();
}
}
Create Controllers For Laravel 6 ToDo Application
We’ll create two controllers for this Laravel passport authentication project. The first controller will be for the user. The second controller will be for the task. So, let’s create one by one.
php artisan make:controller UserController --resource
php artisan make:controller TaskController --resource
Once, controllers have been created, let’s add the functionalities.
// UserController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use App\User;
class UserController extends Controller
{
private $success_status = 200;
public function registerUser(Request $request)
{
// --------------------- [ User Registration ] ---------------------------
$validator = Validator::make($request->all(),
[
'name' => 'required',
'email' => 'required',
'password' => 'required'
]
);
// if validation fails
if($validator->fails()) {
return response()->json(["validation errors" => $validator->errors()]);
}
$input = array(
'name' => $request->name,
'email' => $request->email,
'password' => bcrypt($request->password)
);
$user = User::create($input);
return response()->json(["success" => true, "status" => "success", "user" => $user]);
}
// --------------------------- [ User Login ] ------------------------------
public function loginUser(Request $request) {
$validator = Validator::make($request->all(),
[
'email' => 'required',
'password' => 'required',
]
);
// check if validation fails
if($validator->fails()) {
return response()->json(["validation errors" => $validator->errors()]);
}
$email = $request->email;
$password = $request->password;
$user = DB::table("users")->where("email", "=", $email)->first();
if(is_null($user)) {
return response()->json(["success" => false, "message" => "Email doesn't exist"]);
}
if(Auth::attempt(['email' => request('email'), 'password' => request('password')])) {
$user = Auth::user();
$token = $user->createToken('token')->accessToken;
$success['success'] = true;
$success['message'] = "Success! you are logged in successfully";
$success['token'] = $token;
return response()->json(['success' => $success ], $this->success_status);
}
else {
return response()->json(['error' => 'Unauthorised'], 401);
}
}
// ---------------------------- [ Use Detail ] -------------------------------
public function userDetail() {
$user = Auth::user();
return response()->json(['success' => $user], $this->success_status);
}
// -------------------------- [ Edit Using Passport Auth ]--------------------
public function update(Request $request) {
$user = Auth::user();
$validator = Validator::make($request->all(),
[
'name' => 'required',
'email' => 'required',
'password' => 'required',
]
);
// if validation fails
if($validator->fails()) {
return response()->json(["validation errors" => $validator->errors()]);
}
$userDataArray = array(
'name' => $request->name,
'email' => $request->email,
'password' => bcrypt($request->password)
);
$user = User::where('id', $user->id)->update($userDataArray);
return response()->json(['success' => true, 'message' => 'User updated successfully']);
}
// ----------------------------- [ Delete User ] -----------------------------
public function destroy() {
$user = Auth::user();
$user = User::findOrFail($user->id);
$user->delete();
return response()->json(['success' => true, 'message' => 'User deleted successfully']);
}
}
In the above controller file, I have added functions for creating a new user, user login, user detail, update user and delete the user.
Laravel 6 Basic CRUD Application with Form Validation
Add Routes For UserController
Navigate to the routes->api.php and then paste the below code.
// --------------- [ User Controller Route] ------------
Route::post('user-registration', 'UserController@registerUser');
Route::post('user-login', 'UserController@loginUser');
// -------------------- [ Auth Tokens ]
Route::group(['middleware' => 'auth:api'], function () {
Route::get('user-detail', 'UserController@userDetail');
Route::post('update-user', 'UserController@update');
});
Open the postman and let’s check the APIs.
In the user registration the name, email, and password are required.
User Registration API
http://localhost:8000/api/user-registration
Enter the above URL in the postman and change request type to POST. Try to hit the API. It will return the validation errors.
Add the fields and values and hit enter. It will create the user and save the record into the database.
API For User Login
http://localhost:8000/api/user-login
After the validation passed, the successful user login will generate a token.
User Detail
http://localhost:8000/api/user-detail
In the user detail API, you will need to pass the token in the header. So, the following keys and values will need to be passed with the API request.
Authorization Bearer YourToken
Content-Type application/json
Update User API
Delete User
http://localhost:8000/api/delete-user
In the next step, we will work on the TaskController. The user can create a new task, retrieve the tasks, update and delete the task based on the task id. But in all these operations, we will require the user’s token key. So that we can identify the task of the user. On the basis of the user token, the task will be synced with the user.
TaskController Functions
Add the below code in the TaskController.php file. Here, the user can perform task related operations.
// TaskController.php
<?php
namespace App\Http\Controllers;
use App\Task;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Auth;
use function GuzzleHttp\Promise\all;
class TaskController extends Controller
{
private $success_status = 200;
// ------------- [ Create New Task ] ----------------
public function createTask(Request $request)
{
$user = Auth::user();
$validator = Validator::make($request->all(),
[
'task_title' => 'required',
'category' => 'required',
'description' => 'required',
]
);
if($validator->fails()) {
return response()->json(["validation_errors" => $validator->errors()]);
}
$taskInput = array(
'task_title' => $request->task_title,
'category' => $request->category,
'description' => $request->description,
'user_id' => $user->id
);
$task = Task::create($taskInput);
if(!is_null($task)) {
$success['status'] = "success";
$success['data'] = $task;
}
return response()->json(['success' => $success], $this->success_status);
}
// --------------- [ Task Listing Based on User Auth Token ] ------------
public function taskListing()
{
$user = Auth::user();
$tasks = Task::where('user_id', $user->id)->get();
$success['status'] = "success";
$success['data'] = $tasks;
return response()->json(['success' => $success]);
}
// ---------------------- [ Task Detail ] -----------------------
public function taskDetail($task_id)
{
$user = Auth::user();
$task = Task::where("id",$task_id)->where('user_id', $user->id)->first();
if(!is_null($task)) {
$success['status'] = "success";
$success['data'] = $task;
return response()->json(['success' => $success]);
}
else {
$success['status'] = "failed";
$success['message'] = "Whoops! no detail found";
return response()->json(['success' => $success]);
}
}
// ------------------ [ Update Task ] ------------------
public function updateTask(Request $request)
{
$user = Auth::user();
$validator = Validator::make($request->all(),
[
'task_id' => 'required',
'task_title' => 'required',
'category' => 'required',
'description' => 'required'
]
);
// if validation fails
if($validator->fails()) {
return response()->json(["validation errors" => $validator->errors()]);
}
$inputData = array(
'task_title' => $request->task_title,
'category' => $request->category,
'description' => $request->description
);
$task = Task::where('id', $request->task_id)->where('user_id', $user->id)->update($inputData);
if($task == 1) {
$success['status'] = "success";
$success['message'] = "Task has been updated successfully";
}
else {
$success['status'] = "failed";
$success['message'] = "Failed to update the task please try again";
}
return response()->json(['success' => $success], $this->success_status);
}
// ---------------------- [ Delete Task ] --------------------------
public function deleteTask($id) {
$user = Auth::user();
$task = Task::findOrFail($id);
if(!is_null($task)) {
$response = Task::where('id', $id)->delete();
if($response == 1) {
$success['status'] = 'success';
$success['message'] = 'Task has been deleted successfully';
return response()->json(['success' => $success], $this->success_status);
}
}
}
}
Add Routes For TaskController
Add the following routes for the TaskController in the routes/api.php file. These routes must be added inside the middleware auth.
Route::post('create-task', 'TaskController@createTask');
Route::get('task-listing', 'TaskController@taskListing');
Route::get('task-detail/{task_id}', 'TaskController@taskDetail');
Route::post('update-task', 'TaskController@updateTask');
Route::delete('delete-task/{task_id}', 'TaskController@deleteTask');
After adding the routes the complete routes will be like below.
// api.php
// --------------- [ User Controller Route] ------------
Route::post('user-registration', 'UserController@registerUser');
Route::post('user-login', 'UserController@loginUser');
// -------------------- [ Auth Tokens ]-----------------------
Route::group(['middleware' => 'auth:api'], function () {
Route::get('user-detail', 'UserController@userDetail');
Route::post('update-user', 'UserController@update');
Route::delete('delete-user', 'UserController@deleteUser');
Route::post('create-task', 'TaskController@createTask');
Route::get('task-listing', 'TaskController@taskListing');
Route::get('task-detail/{task_id}', 'TaskController@taskDetail');
Route::post('update-task', 'TaskController@updateTask');
Route::delete('delete-task/{task_id}', 'TaskController@deleteTask');
});
Create Task API
For creating a new task, hit the below API in the postman. Don’t forget to add authorization with Bearer token in the header. Without the authorization key, it will not allow you to hit the API request.
http://localhost:8000/api/create-task
API For Listing All Task
For listing the task hit the below API. It will return all tasks which have been created by the user. Here also you will need to pass the authorization and bearer token.
http://localhost:8000/api/task-listing
How to Send Email in Laravel 6 Via Gmail Using SMTP
Task Detail API
In case, if the user wants to get the single task then using this API the single task will list. This will be based on the task id.
http://localhost:8000/api/task-detail/1
Update Task By Task Id
For updating the task, we will need to pass the task id along with the task data. Here, I have passed the header for the authorization token.
http://localhost:8000/api/update-task/
Delete Task By Task Id
At last, the user can delete the task by the task id. Also, the user authorization key is required.
http://localhost:8000/api/delete-task/1
Bingo! we have completed the Todo application.
Conclusion
Finally, we learned how to create the REST APIs with Passport Authentication for ToDo application in the Laravel 6. This is a small demonstration of a project and you can implement it in real projects. Laravel 6 passport authentication is a good approach to secure the APIs request in the Laravel. Hope it will help you in implementing your projects.
Leave a Reply