Courses

[NEW] Flutter 3 Mobile App with Laravel 12 API

API Authentication

An API without authentication is like a house without a door. So, let's secure our API by adding an authentication system to it:

  • Set up Sanctum Middleware
  • Create a User Registration API
  • Create a User Login API

Let's get secure!


Setting Up Authentication Middleware

Let's start by securing our API endpoint with a Middleware:

routes/api.php

// ...
 
Route::group(['middleware' => 'auth:sanctum'], function () {
Route::apiResource('categories', CategoryController::class);
Route::apiResource('transactions', TransactionController::class);
});

Now, we can immediately try to make an API request using Postman:

This is good! However, we need to create a user registration and login API to authenticate our users.


Registering our First User

So, let's create a way to register a new user. For this, we need a new Controller:

php artisan make:controller Api/AuthController

In there, let's add a new method to register a user:

app/Http/Controllers/Api/AuthController.php

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\Rules\Password;
 
// ...
 
public function register(Request $request): string
{
$request->validate([
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => ['required', 'confirmed', Password::defaults()],
'device_name' => 'required',
]);
 
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
]);
 
return $user->createToken($request->device_name)->plainTextToken;
}

As you can see, we are doing basic validation and user creation. But in the end, we are trying to create a token for the user. This is where we need to modify our User model:

app/Models/User.php

use Laravel\Sanctum\HasApiTokens;
 
// ...
 
class User extends Authenticatable
{
/** @use HasFactory<UserFactory> */
use HasFactory, Notifiable;
use HasFactory, Notifiable, HasApiTokens;
// ...

Now, let's add a new route for this method:

routes/api.php

 
use App\Http\Controllers\Api\AuthController;
 
// ...
 
Route::group(['middleware' => 'auth:sanctum'], function () {
// ...
});
 
Route::post('/auth/register', [AuthController::class, 'register']);

Now we are ready to make a Postman request to see it in action:

We have received a token back! We can use this token in the Bearer header to authenticate our requests:


Authenticating our User

The last thing to do is to create a login/logout API endpoint. They both will follow the same pattern as the register method:

app/Http/Controllers/Api/AuthController.php

use Illuminate\Validation\ValidationException;
 
// ...
 
public function login(Request $request): string
{
$request->validate([
'email' => 'required|email',
'password' => 'required',
'device_name' => 'required',
]);
 
$user = User::where('email', $request->email)->first();
 
if (!$user || !Hash::check($request->password, $user->password)) {
throw ValidationException::withMessages([
'email' => ['The provided credentials are incorrect.'],
]);
}
 
return $user->createToken($request->device_name)->plainTextToken;
}
 
public function logout(Request $request)
{
$user = User::where('email', $request->email)->first();
 
if ($user) {
$user->tokens()->delete();
}
 
return response()->noContent();
}

And the routes:

routes/api.php

Route::post('/auth/login', [AuthController::class, 'login']);
Route::post('/auth/register', [AuthController::class, 'register']);
Route::post('/auth/logout', [AuthController::class, 'logout'])->middleware(['auth:sanctum']);

That's it! We can now try to log in using the user we just created:

As you can see, our token starts with 2| instead of 1|, which we had previously. This means that we have new token issues for our users.

That's it for our authentication setup. Sanctum is powerful enough that this was all we needed to do to secure our API.


In the next lesson, we will look at a simple multi-tenancy setup for our users. The goal here is for each of our users to manage their own categories and transactions without seeing other users' data.


Check out the GitHub Commit

Previous: Transactions CRUD
avatar

I would add the sanctum middleware on the logout route. Like this: Route::post('/auth/logout', [AuthController::class, 'logout'])->middleware('auth:sanctum'); . It's more secure.

avatar
You can use Markdown
avatar
You can use Markdown