REST or RESTful is a web service that is used to send requests to the server for accessing the web resources. It stands for REpresentational State Transfer which returns the response with the stateless operation. A RESTful API uses HTTP Requests to perform the GET, POST, PUT, and DELETE operations on the data. These requests are used to handle and manipulate the data on the basis of the requests. In Laravel 6 REST API, we can send HTTP requests to the server with API routes. Today, I’m going to show you how to create RESTful APIs in Laravel 6 with passport authentication. In the previous post, I have shown you the User Registration and Login with Authentication.
Prerequisites
To create this project, I assume that you have the composer installed in your system and you have the PHP (>=7.3.9) with MySQL > 5. Also, you must have some basic concepts of Web Services or RESTful APIs. For API testing, I will be using POSTMAN. So, it must be installed in your system. You can use Swagger Inspector or Curlx.
Laravel 6 REST API
I am going to start with a new project of Laravel 6 in which I will create RESTful APIs for the Blog. Previously, I have shown you how Laravel authentication works for User registration and login. But if we talk about the APIs then we know that it is a stateless protocol that doesn’t maintain the session of state. That’s why it is the most important part of any APIs to secure it. Laravel 6 comes with the Passport authentication which provides OAuth2 server implementation.
How to Upload Files and Images in Laravel 6 with Validation
I will install passport authentication then I will create the APIs for the user registration and login with auth. Then on the basis of the auth token, the logged-in user can create the new posts. The user auth token will be unique for every user. So, let’s start from very initial step.
Step 1: Create a New Project
Open the command prompt or terminal and type the below command to create a new project.
composer create-project --prefer-dist laravel/laravel blog-rest-api
It will take a few minutes to create a new project and will install the latest version of the Laravel (Laravel 6.0) in the project directory.
Laravel 6 CRUD Application For Beginners
Step 2: Create and Configure the Database
Now, we’ll create a database in MySQL. Open MySQL or if you are using phpMyAdmin then go the SQL tab and create a new database there.
CREATE DATABASE laravel6_rest_api;
I have created a new database laravel6_rest_api
in the MySQL 8 command line.
Now, you will need to configure the database details in the .env file.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel6_rest_api
DB_USERNAME=root
DB_PASSWORD=root
In my case, I have updated my database details as shown above.
Step 3: Install Passport in Laravel 6
Once your project and the database has been created, move to the project directory. Now, inside the project files, we will install the passport auth which will add all the necessary auth files automatically for creating the auth tokens for the user. Therefore type the below command to install the passport auth.
Open the terminal or command prompt and enter the below command. It will create its own migration files to create and maintain the tokens.
composer require laravel/passport
How to Integrate Laravel 6 Application with Firebase Realtime Database
As you can see, the Passport has been installed in the Laravel 6 REST APIs project. Some migration files will be added internally so you will need to migrate.
Step: 4 Create Model and Migration
In the Laravel, we have the User model default inside the app folder. Therefore according to the Blog application, we will need to create a Post model. The user will have access to add new posts, retrieve posts, edit a post, and delete a post. Replace User.php code with the below code.
// User.php
<?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',
];
}
In the above code, I have included the namespace HasApiTokens and used it.
Add AuthServiceProvider
Now, navigate to the Providers->AuthServiceProvider.php and paste the below code.
// 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 RESTful APIs for ToDo Application with Passport Auth
Add Authentication Guards
Then go to the config->auth.php and in the Authentication Guards section add the following code.
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
Here, we have successfully configured passport auth.
Users Table Migration
We have the default migration of the users
table. Here, I have set the below schema for the users
table.
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, we will require to create one more model for the post and also the migration file for the posts table.
Create Post Model and Migration
Create a new model for the post with the below command. When you will enter this command, it will add a migration file (create_post_table.php).
php artisan make:model Post --migration
Now, open the create_post_table.php migration file and add some fields for the blog post.
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('title');
$table->string('slug');
$table->string('featured_img');
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
$table->timestamps();
});
}
In this table migration, I have set the foreign key of field user_id
which is a primary key on the users
table. So, that we can identify each post that has been posted by the user.
Migrate Table Schema
After creating the table schema in the migration file, we need to migrate it. In the migration, the tables will be created with the defined schema. Also, it will add the necessary tables of the Passport auth with default fields in the database.
php artisan migrate
After migrating the database tables, you can see the tables in MySQL which have been created during the migration.
How to Send Email in Laravel 6 Via Gmail Using SMTP
Step 5: Install Passport
In the next step, we’ll have to install the Passport for the authentication. This will add the encryption key with a PAC (Personal Access Client). The personal access client has the Client Id and the Client Secret (Token key). This grants permission for the users in which the access token will be generated.
php artisan passport:install
Once, you have done with the above steps, create the controllers.
Step 6: Create Controllers For Laravel REST API
According to this blog application, we’ll need to create two controllers. The first controller will be for the User in which the user’s activity will be maintained. The second controller will be for the Post in which the blog post will be managed. So, let’s create two controllers.
php artisan make:controller UserController
php artisan make:controller PostController
Enter the above commands for creating both controllers.
Step 7: Create Laravel 6 Rest API For User
After creating the controllers, we will require to add functionalities for user registration and user login. So for these, add the below code snippet in the UserController.php file.
// UserController.php
<?php
namespace App\Http\Controllers;
use App\User;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
class UserController extends Controller
{
private $successStatus = 200;
//----------------- [ Register user ] -------------------
public function registerUser(Request $request) {
$validator = Validator::make($request->all(),
[
'name' => 'required|min:3',
'email' => 'required|email',
'password' => 'required|alpha_num|min:5',
'confirm_password' => 'required|same:password'
]
);
if($validator->fails()) {
return response()->json(['Validation errors' => $validator->errors()]);
}
$input = array(
'name' => $request->name,
'email' => $request->email,
'password' => bcrypt($request->password),
'address' => $request->address,
'city' => $request->city
);
// check if email already registered
$user = User::where('email', $request->email)->first();
if(!is_null($user)) {
$data['message'] = "Sorry! this email is already registered";
return response()->json(['success' => false, 'status' => 'failed', 'data' => $data]);
}
// create and return data
$user = User::create($input);
$success['message'] = "You have registered successfully";
return response()->json( [ 'success' => true, 'user' => $user ] );
}
// -------------- [ User Login ] ------------------
public function userLogin(Request $request) {
if(Auth::attempt(['email' => request('email'), 'password' => request('password')])) {
// getting auth user after auth login
$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->successStatus);
}
else {
return response()->json(['error'=>'Unauthorised'], 401);
}
}
}
In the above code, I have created two functions. The first function is to register a new user with the tokens. The second function is for the user login.
Step: 8 Add Routes For UserController
In the Laravel, the routes are separated for Web, API, Console, etc. So, for the APIs, we will add routes in the routes->api.php
file.
Add the below routes there.
// ------------- Routes For User Controller ------------
Route::post('register', 'UserController@registerUser');
Route::post('login', 'UserController@userLogin');
Also, you can check the route list in the Laravel.
php artisan route:list
After adding the routes, we’ll run the application to test the APIs.
php artisan serve
The above command will run your application on the localhost and the default port will be 8000. Now, for testing the APIs, I will use Postman. So, here I have opened the Postman and I will make POST request for user registration.
1. POST Request For Laravel 6 REST API
In the first step of a POST request, we’ll register a user for which, we have created the table in the database.
- Open the Postman.
- Enter the URL:
http://localhost:8000/api/register
- Select the request type to POST.
- Click on the Body section and under the form-data enter the fields with value as shown below.
After successful registration of the user, it will return the success with the registered user details as shown above.
2. POST Request For User Login
Once, you have registered with your email and password, the next API request will be for the login. Here, the request type will be POST.
- For the login this will be the URL:
http://localhost:8000/api/login
- Select the request type to POST.
- Similarly, as the above request, under the form-data enter the fields email and password with the values and hit Send.
If the user credentials are correct, it will show the success message as shown above.
RESTful APIs For Blog Post
Now, we’ll create APIs for creating a new post and retrieving the created posts. In this case, the user who is logged in will have access to create a new post. Similarly, the logged-in user can retrieve only own posts. These functionalities will be possible by only access tokens. That means the API for the user login will create and return a unique access token every time. So to maintain this session we’ll need to pass this token into the Header as authorization. So through the access token, we’ll manage the session of the current user.
Add Fillable Data For Post
In the Post model, we will have to define the fillable data. So, just navigate to the app\Post.php (model) and add the below snippet there. We’ll have to define what fields are going to save into the database.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
// mass assignment
protected $fillable = [
'title', 'slug', 'featured_img', 'user_id'
];
}
Create and Retrieve Posts
Once, you have set the fillable data. We will need to add the functions for creating a new post and retrieving the posts created by the user. Therefore, open the PostController.php file and paste the below code.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Post;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Auth;
use Illuminate\Auth\AuthenticationException;
class PostController extends Controller
{
//------------- [ Create new Post ] ----------------
public function createPost(Request $request) {
$img_name = "";
// validate input
$validator = Validator::make($request->all(),
[
'title' => 'required',
]
);
// if validation fails
if($validator->fails()) {
return response()->json(["validation errors" => $validator->errors()]);
}
// Retrieve User with acccess token
$user = Auth::user();
// Upload Featured Image
$validator = Validator::make($request->all(),
['featured_img' => 'required|mimes:jpeg,png,jpg,bmp|max:2048']);
// if validation fails
if($validator->fails()) {
return back()->withErrors($validator->errors());
}
if($file = $request->file('featured_img')) {
$img_name = time().time().'.'.$file->getClientOriginalExtension();
$target_path = public_path('/uploads/');
$file->move($target_path, $img_name);
// Creating slug
$slug = str_replace(" ", "-", strtolower($request->title));
$slug = preg_replace('/[^A-Za-z0-9\-]/', '', $slug);
$slug = preg_replace('/-+/', '-', $slug);
// creating array of inputs
$input = array(
'title' => $request->title,
'slug' => $slug,
'featured_img' => $img_name,
'user_id' => $user->id
);
// save into database
$post = Post::create($input);
}
return response()->json(["success" => true, "data" => $post]);
}
// --------- [ Post Listing By User Token ] -------------
public function postListing() {
// Get user of access token
$user = Auth::user();
// Listing post through user id
$posts = Post::where("user_id", $user->id)->get();
return response()->json(["success" => true, "data" => $posts]);
}
}
- In the above code, I have created two functions yet.
- The first function createPost() has defined for creating a new blog post.
- At very first, I have added the validator to validate the input that is post title and then for featured image.
- If these validations will pass, then it will call the Auth user through the access token which will be passed through the header in the API request.
- On the basis of the access token, the user data will be returned. Then, I have got the user id and passed the id with the blog post which is going to be created.
- Then, I have uploaded the featured image with proper image validation.
- At last, I have created an array of inputs and using the Laravel create() function saved the data into the database and returned it with the API response.
Auth APIs Inside Middleware
At last, we’ll have to add routes for the HTTP request that will be called with the auth token. So, for this, you will need to add these routes in the middleware as shown below.
// ----------------- Auth Tokens --------------
Route::group(['middleware' => 'auth:api'], function () {
Route::post('create-post', 'PostController@createPost');
Route::get('post-listing', 'PostController@postListing');
});
The above routes APIs will call with the access token only. So for this, we will have to pass the Bearer Token in the Header of the HTTP request.
Here are the following key and value which will need to pass in the Header of the API request.
KEY : Authorization
VALUE : Bearer YOUR_ACCESS_TOKEN
KEY : Accept
VALUE : application/x-www-form-urlencoded
KEY : Content-Type
VALUE : application/json
API For Create Post with Access Token
- Type
http://localhost:8000/api/create-post
- Copy the token key of login API.
- Now, in the header section add the keys and values as shown below.
- In the Authorization just pass Bearer with the copied token key.
- Then in the Body section, click on the form-data and add the title and featured image as shown below.
- Now hit enter.
- The inserted post will be returned with success.
API for Post Listing with Auth token
- Enter the URL
http://localhost:8000/api/post-listing
- Pass Authorization Bearer as the same as the above.
- Hit the send button. You will get the response as success with data.
Conclusion
Finally, we have created the Laravel 6 REST API for a Blog application with Passport Authentication. The authentication in the REST APIs is very important for the security purpose. If access token will not be used in the APIs then the HTTP request of any APIs can be accessed from anywhere. Therefore, I hope, you will understand the concept to build APIs. Using this concept, you can create and secure your RESTful APIs. If you got any difficulties in this post, then ask me through the comments.
Deepak Thakur says
Truly a great a helpful article especially for the beginners. Very well explained. Cheers!!
Hemant says
Can we use JWT authentication in Laravel for REST APIs?
Umesh Rana says
Yes, we can use JWT authentication too instead of Passport.
Leo says
So, I want to offer to clients API access to some of my data and process, I undersand that I have to give my clients a public key and a secret key for them to access my APIs. Can I use Laravel Passport with that? What would you recommed to control how many times can a user call my API so I can charge accordingly?
Serik says
Hi, why do I have when trying to process the page “create-post” returns the code-200, and there are no records in the database.
Umesh Rana says
Your HTTP request status is ok. It means there is a problem with the configuration with the database and the tables. Please make sure you configured the correct database table for which you are creating the RESTful APIs. Would you like to share your code so that I can help you out with debugging?
bhavana says
/opt/lampp/htdocs/blog-rest-api/vendor/laravel/framework/src/Illuminate/Foundation/helpers.php(782): Illuminate\Routing\UrlGenerator->route(‘login’, Array, true)a
am getting this error
Umesh Rana says
Please check the route that you have defined in the routes/api.php. If it is possible then please share your code, so that I can help you.
Mauro says
When I try to create a post I get this error
Illuminate\Database\QueryException: SQLSTATE[42S22]: Column not found: 1054 Unknown column ‘api_token’ in ‘where clause’ (SQL: select * from `users` where `api_token` = API_TOKEN) in file E:\laragon\www\blog-rest-api\vendor\laravel\framework\src\Illuminate\Database\Connection.php on line 669
Umesh Rana says
You are trying to get the api_token from the users table that doesn’t exist. Please make sure, you have installed the passport authentication correctly. You can check the tables inside the database.