How To Create A Secure CRUD RESTful API in Laravel 8 and 7 Using Laravel Passport - DEV Community
How To Create A Secure CRUD RESTful API in Laravel 8 and 7 Using Laravel Passport - DEV Community
54 12
Good day, today we are going to be coding strictly in the backend, we are going to
convert our Laravel 8 CRUD app to RESTful APIs. API is a software intermediary that
allows two applications to talk to each other. Somethings you might need to create
an app that can be run on different languages or frameworks, for example, you can
use Laravel to create the backend for your application while the frontend might run
on any JavaScript frameworks. API allows two or more programs to communicate
with each other.
There are different types of APIs, but today we are going to concentrate on RESTful
APIs. REST stands for Representational State Transfer, while API stands for
Application Programming Interface. You can read more about API from the internet
or other programming material.
This will automatically create a laravel 8 app and some couple of things have been
set up, we don’t need to copy and rename the env.example file, Laravel 8 does that
automatically for us
Another important thing about Laravel 8, you don’t need to generate APP_KEY, this
new version will also generate it for us.
After installation, then we need to migrate, but before we run our migration
command, we need to specify the default string length, else, we are going to run into
errors. So go to app/Providers/AppServiceProvider.php and add this to the boot
function
Schema::defaultstringLength(191);
use Illuminate\Support\Facades\Schema;
This command will also create "personal access" and "password grant" clients which
will be used to generate access tokens.
use HasApiTokens,
Passport::routes();
To the boot method, also add the path before the class at the top
use Laravel\Passport\Passport;
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('projects');
}
}
We need to update our Project Model so that it can be able to accept the fields. We
need to add a protected $fillable method that will contain the fields that a user of the
app can fill, this helps to prevent someone from hacking into the app through input
fields.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name',
'location',
'introduction',
'cost',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'cost' => 'int',
];
}
This will create a folder in the app directory called Resources and also a file
ProjectResource.php inside the resources.
Step 11: Create our Controllers
The Controller is responsible for the direction of the flow of data and an interface
between the user and the database and views. In this case, we are not interacting
with views now because we are dealing with API, so our response will be in JSON
format. The standard for RESTful APIs is to send the response in JSON.
We are going to be creating two controllers, the first will be the Authentication
Controller and the second is our Project Controller, we need the Authentication
Controller in order to generate the token to use in Project Controller.
This will create a folder called API in App/Http/Controllers. It will also create a new
file called AuthController.php. Click on AuthController.php and update it with the
following code.
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
$validatedData['password'] = Hash::make($request->password);
$user = User::create($validatedData);
$accessToken = $user->createToken('authToken')->accessToken;
if (!auth()->attempt($loginData)) {
return response(['message' => 'This User does not exist, check y
}
$accessToken = auth()->user()->createToken('authToken')->accessToken
The --api switch will create our Controller without the create and edit methods, those
methods will present HTML templates.
Go to App/Http/Controller/API, and click on ProjectController, copy the code below
and update the methods.
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Models\Project;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use App\Http\Resources\ProjectResource;
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$data = $request->all();
$validator = Validator::make($data, [
'name' => 'required|max:255',
'description' => 'required|max:255',
'cost' => 'required'
]);
if ($validator->fails()) {
return response(['error' => $validator->errors(), 'Validation Er
}
$project = Project::create($data);
/**
* Display the specified resource.
*
* @param \App\Models\Project $project
* @return \Illuminate\Http\Response
*/
public function show(Project $project)
{
return response(['project' => new ProjectResource($project), 'messag
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\Models\Project $project
* @return \Illuminate\Http\Response
*/
public function update(Request $request, Project $project)
{
$project->update($request->all());
/**
* Remove the specified resource from storage.
*
* @param \App\Models\Project $project
* @return \Illuminate\Http\Response
*/
public function destroy(Project $project)
{
$project->delete();
1. The index method will retrieve all the projects in the database with a success
message (Retrieved successfully) and returns a status code of 200.
2. The store method will validate and store a new project, just like the AuthController,
and returns a status code of 201, also a message of "Created successfully".
3. The show method will retrieve just one project that was passed through the
implicit route model binding, and also returns an HTTP code of 200 if successful.
4. The update method receives the HTTP request and the particular item that needs
to be edited as a parameter. It updates the project and returns the appropriate
response.
5. The destroy method also receives a particular project through implicit route
model binding and deletes it from the database.
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\API\AuthController;
use App\Http\Controllers\API\ProjectController;
/*
|--------------------------------------------------------------------------
| 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::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
Route::apiResource('projects', ProjectController::class)->middleware('auth:a
We added a register route and login routes which are post routes and also an
apiResource route for projects utilizing the auth:api middleware.
register a user
In other to access the projects routes, we must authenticate the user, in other to
achieve this, we must add the user's token.
Copy the access token generated for the user when the user login in, click on
Authorization on postman and select the type, Bearer Token, and paste the token by
the input field by the right.
Update a project
Delete a project
Finally, we have come to the end of the article, if you follow the article religiously, you
will not make a mistake, but in case you can't follow all through, this is the link to the
repo
You can encourage me by clicking the heart button to show love, you are can also
leave a comment, suggestion, etc. You are also free to contact me through any of my
contact details.
👋 Before you go
Do your career a favor. Join DEV. (The website you're on right now)
Get started
You have not told us how to deal with access token because when I entered
data in 127.0.0.1:8000/api/register and in 127.0.0.1:8000/api/projects route
it shows login route not found and after adding this header X-Requested-With
I am getting unauthorized message and on register link it's showing
response to unauthorized access ?
how to deal with this I have 0 rows in user db ? show I make fake data first to
generate access token
You should have modified the api routes not the web routes. I made such
mistake at the beginning that resulted none of the url existed.
When I carefully corrected two typos in my scripts following the tutorial it
worked.
Now I figured out your first post is creating mess because you do not use
token in this route 127.0.0.1:8000/api/projects this is wrong implementation
as it is not using using token we make with passport auth.
Hi Mian, could you please give more details of this? It worked okay as I
tried.
Target class
[App\Http\Controllers\App\Http\Controllers\API\ProjectController] does not
exist
please help me
Hi @vincenttetteh ! In case you're still having this issue, you may refer to
this link:
stackoverflow.com/questions/638079...
Illuminate\Database\QueryException
at vendor/laravel/framework/src/Illuminate/Database/Connection.php:678
674▕ // If an exception occurs when attempting to run a query, we'll format
the error
675▕ // message to include the bindings with SQL, which will make this
exception a
676▕ // lot more helpful to the developer instead of just the database's
errors.
677▕ catch (Exception $e) {
➜ 678▕ throw new QueryException(
679▕ $query, $this->prepareBindings($bindings), $e
680▕ );
681▕ }
682▕
34 artisan:37
Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\
Console\Input\ArgvInput),
Object(Symfony\Component\Console\Output\ConsoleOutput))
Your database is not set property or you have not any database with this
name testing.......
return response([
'message' => 'You have been successfully logged out.',
], 200);
}
This makes sense I however got this error, do not know why,
Call to a member function token() on null
benjaminv • Jul 13 '21
I figured out what happened. Before you can log a user out via API, you
will need to pass authentication first and then log your login off.
Therefore the route logout has to be underneath the middleware auth.
For convenience I grouped it with the /user route that is used in this
tutorial.
Route::middleware('auth:api')->group(function (){
Route::get('/user', function (Request $request) {
return $request->user();
});
Route::post('logout', [
AuthController::class, 'logout'
]);
});
Thankyou Sir
Symfony\Component\Routing\Exception\RouteNotFoundException
Route [login] not defined.
192.168.20.105:8085/api/projects
this works for me - its important to register a user first and get their token
back and use it in future requests.
Auth0 PROMOTED
Easy to implement, endless possibilities
With a few lines of code, you can have Auth0 by Okta integrated in any app
written in any language and any framework. 🚀 Start building for free today.
Sign up now
Kingsconsult
I am Kingsley Okpara, a Python and PHP Fullstack Web developer and tech writer, I also have
extensive knowledge and experience with JavaScript while working on applications developed
with VueJs.
LOCATION
Lagos, Nigeria
EDUCATION
Bsc.ed Mathematics, Enugu State University of Science and Technology, Enugu, Nigeria
WORK
Mid-level Web Developer at Plexada-Si
JOINED
Aug 5, 2019
AWS PROMOTED
A data pipeline of helpful info
Fluent in SQL? This show’s for you.
Do you have questions about building efficient data architectures, navigating data virtualization
issues, or other common challenges? Get answers live from experts.
Learn More