Laravel 8 Api tutorial #2 Api authentication
Introduction
This tutorial will guide you through the process of setting up API authentication in a Laravel 8 application. We'll create a simple API with endpoints for user registration, login, and retrieving the authenticated user's information.
Prerequisites
- Basic knowledge of Laravel
- Familiarity with PHP and the command line
Steps
Setting up the API
- Create a new Laravel project using the Laravel new command.
- Enable API mode by setting the API option to true in the config/app.php file.
- Configure the API routes in the routes/api.php file, including endpoints for user registration, login, and retrieving the authenticated user's information.
- Implementing the Authentication
- Create the AuthController using the php artisan make:controller command.
- Implement the register and login methods in the AuthController:
- The register method will validate the user input, create a new user, and return an access token.
- The login method will validate the user's credentials, and if successful, return an access token.
- Implement the user method in the AuthController to return the authenticated user's information.
- Protect the authenticated routes using the auth:api middleware.
- Explain how to use the API endpoints for user registration, login, and retrieving the authenticated user's information.
- Provide example requests and responses for each endpoint.
Step 1: Install Laravel 8
I am going to explain step by step from scratch so, we need to get a fresh Laravel 8 application using the bellow command, So open your terminal OR command prompt and run the bellow command:
composer create-project --prefer-dist laravel/laravel blog
Step 2: Use Passport
In this step we need to install Passport via the Composer package manager, so one your terminal and fire the bellow command:
composer require laravel/passport
After successfully installing the package, we are required to get the default migration for creating new passport tables in our database. so let's run the below command.
php artisan migrate
Next, we need to install the passport using the command, Using passport: install command, will create token keys for security. So let's run the command:
php artisan passport:install
Step 3: Passport Configuration
In this step, we have to configure on three place model, service provider, and auth config file. So you have to just follow the change on that file.
In the model, we added the HasApiTokens class of Passport,
In auth.php, we added API auth configuration.
app/Models/User.php
<?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;
/**
* 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',
];
}
config/auth.php
<?php
return [
.....
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
.....
]
Step 4: Add Product Table and Model
next, we require to create migration for posts table using Laravel 8 PHP artisan command, so first fire bellow command:
php artisan make:migration create_products_table
After this command, you will find one file in the following path database/migrations and you have to put the below code in your migration file to create the products table.
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateProductsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->text('detail');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('products');
}
}
After creating the migration we need to run the above migration by the following command:
php artisan migrate
After creating the "products" table you should create a Product model for products, so first create a file in this path app/Models/Product.php and put the below content in the item.php file:
app/Models/Product.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'detail'
];
}
Step 5: Create API Routes
In this step, we will create API routes. Laravel provides an api.php file for writing web services routes. So, let's add a new route to that file.
routes/api.php
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\API\RegisterController;
use App\Http\Controllers\API\ProductController;
/*
|--------------------------------------------------------------------------
| 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('register', [RegisterController::class, 'register']);
Route::post('login', [RegisterController::class, 'login']);
Route::middleware('auth:api')->group( function () {
Route::resource('products', ProductController::class);
});
Step 6: Create Controller Files
in the next step, now we created new controllers as BaseController, ProductController, and RegisterController, I created a new folder "API" in the Controllers folder because we will make alone APIs controller, So let's create both controllers:
app/Http/Controllers/API/BaseController.php
<?php
namespace App\Http\Controllers\API;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller as Controller;
class BaseController extends Controller
{
/**
* success response method.
*
* @return \Illuminate\Http\Response
*/
public function sendResponse($result, $message)
{
$response = [
'success' => true,
'data' => $result,
'message' => $message,
];
return response()->json($response, 200);
}
/**
* return error response.
*
* @return \Illuminate\Http\Response
*/
public function sendError($error, $errorMessages = [], $code = 404)
{
$response = [
'success' => false,
'message' => $error,
];
if(!empty($errorMessages)){
$response['data'] = $errorMessages;
}
return response()->json($response, $code);
}
}
app/Http/Controllers/API/RegisterController.php
<?php
namespace App\Http\Controllers\API;
use Illuminate\Http\Request;
use App\Http\Controllers\API\BaseController as BaseController;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Validator;
class RegisterController extends BaseController
{
/**
* Register api
*
* @return \Illuminate\Http\Response
*/
public function register(Request $request)
{
$validator = Validator::make($request->all(), [
'name' => 'required',
'email' => 'required|email',
'password' => 'required',
'c_password' => 'required|same:password',
]);
if($validator->fails()){
return $this->sendError('Validation Error.', $validator->errors());
}
$input = $request->all();
$input['password'] = bcrypt($input['password']);
$user = User::create($input);
$success['token'] = $user->createToken('MyApp')->accessToken;
$success['name'] = $user->name;
return $this->sendResponse($success, 'User register successfully.');
}
/**
* Login api
*
* @return \Illuminate\Http\Response
*/
public function login(Request $request)
{
if(Auth::attempt(['email' => $request->email, 'password' => $request->password])){
$user = Auth::user();
$success['token'] = $user->createToken('MyApp')-> accessToken;
$success['name'] = $user->name;
return $this->sendResponse($success, 'User login successfully.');
}
else{
return $this->sendError('Unauthorised.', ['error'=>'Unauthorised']);
}
}
}
app/Http/Controllers/API/ProductController.php
<?php
namespace App\Http\Controllers\API;
use Illuminate\Http\Request;
use App\Http\Controllers\API\BaseController as BaseController;
use App\Models\Product;
use Validator;
use App\Http\Resources\Product as ProductResource;
class ProductController extends BaseController
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$products = Product::all();
return $this->sendResponse(ProductResource::collection($products), 'Products retrieved successfully.');
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$input = $request->all();
$validator = Validator::make($input, [
'name' => 'required',
'detail' => 'required'
]);
if($validator->fails()){
return $this->sendError('Validation Error.', $validator->errors());
}
$product = Product::create($input);
return $this->sendResponse(new ProductResource($product), 'Product created successfully.');
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
$product = Product::find($id);
if (is_null($product)) {
return $this->sendError('Product not found.');
}
return $this->sendResponse(new ProductResource($product), 'Product retrieved successfully.');
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, Product $product)
{
$input = $request->all();
$validator = Validator::make($input, [
'name' => 'required',
'detail' => 'required'
]);
if($validator->fails()){
return $this->sendError('Validation Error.', $validator->errors());
}
$product->name = $input['name'];
$product->detail = $input['detail'];
$product->save();
return $this->sendResponse(new ProductResource($product), 'Product updated successfully.');
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy(Product $product)
{
$product->delete();
return $this->sendResponse([], 'Product deleted successfully.');
}
}
Step 7: Create Eloquent API Resources
This is a very important step in creating the rest of the API in Laravel 8. You can use eloquent API resources with API. it will help you to make the same response layout of your model object. we used in the ProductController file. now we have to create it using the following command:
php artisan make:resource Product
Now create a new file with a new folder on the following path:
app/Http/Resources/Product.php
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class Product extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'detail' => $this->detail,
'created_at' => $this->created_at->format('d/m/Y'),
'updated_at' => $this->updated_at->format('d/m/Y'),
];
}
}
Now we are ready to run full restful API and also passport API in Laravel. so let's run our example run bellow command for a quick run:
php artisan serve
make sure in details API we will use the following headers as listed below:
'headers' => [
'Accept' => 'application/json',
'Authorization' => 'Bearer '.$accessToken,
]
Here is Routes URL with Verb:
Now simply you can run the above-listed URL as shown in the screenshot:
1) Register API: Verb: GET, URL:http://localhost:8000/api/register
2) Login API: Verb: GET, URL:http://localhost:8000/api/login
3) Product List API: Verb: GET, URL:http://localhost:8000/api/products
4) Product Create API: Verb: POST, URL:http://localhost:8000/api/products
5) Product Show API: Verb: GET, URL:http://localhost:8000/api/products/{id}
6) Product Update API: Verb: PUT, URL:http://localhost:8000/api/products/{id}
7) Product Delete API: Verb: DELETE, URL:http://localhost:8000/api/products/{id}
Conclusion
This tutorial has shown you how to implement a basic API authentication system in a Laravel 8 application. You can now build upon this foundation to add more features, such as password reset, email verification, and role-based access control, to create a secure and robust API for your application.
0 Comments
CAN FEEDBACK
Emoji