LARAVEL API using Sanctum
Packages used to create api are 1. sanctum and 2. Passport we will use sanctum in this guide.
Laravel Sanctum provides a featherweight authentication system. IT solve two separate problems.
- API TOKENS
First, issue API tokens to your users without the complication of OAuth. It store user API tokens in a single database table and authenticating incoming HTTP requests via the Authorization header which should contain a valid API token. So user need to generate a token to use API - SPA Authentication::
https://laravel.com/docs/11.x/sanctum#spa-authentication
How sanctum works:
If login cred are correct it save a token in database and return to user, user need to send that token with every request
Installation:
php artisan install:api
OR
composer require laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
after installation run below command to add new database table personal_access_tokens
php artisan migrate
Set Up Sanctum Middleware:
For APIs, you should add Sanctum's middleware to your api middleware group in app/Http/Kernel.php:
'api' => [
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
Add Sanctum's Middleware to API Authentication: If you are using Sanctum to protect API routes, update the api guard inside your config/auth.php file:
'guards' => [
'api' => [
'driver' => 'sanctum',
'provider' => 'users',
'hash' => false,
],
],
Now, you can use Sanctum to issue tokens or authenticate API requests using tokens.
To issuing tokens for users, your User model should use the Laravel\Sanctum\HasApiTokens trait:
//Models/User.php
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
}
To issue a token, you may use the createToken method. API tokens (SHA-256) hashing before being stored in your database, but you may access the plain-text value of the token using the plainTextToken property of the NewAccessToken instance. You should display this value to the user immediately after the token has been created:
use Illuminate\Http\Request;
Route::post('/tokens/create', function (Request $request) {
$token = $request->user()->createToken($request->token_name);
return ['token' => $token->plainTextToken];
});
//if user is authenticated show him token
ACCESS TOKENS:
foreach ($user->tokens as $token) {
// ...
}
// OR FIND A SINGLE USER THEN
$user->tokens()
Token Abilities
xd learn it
Protecting Routes
To protect routes so that all incoming requests must be authenticated, you should attach the sanctum authentication guard
use Illuminate\Http\Request;
Route::get('/user', function (Request $request) {
return $request->user();
})->middleware('auth:sanctum');
Revoking Tokens
You may "revoke" tokens by deleting them from your database using the tokens relationship
// Revoke all tokens...
$user->tokens()->delete();
// Revoke the token that was used to authenticate the current request...
$request->user()->currentAccessToken()->delete();
// Revoke a specific token...
$user->tokens()->where('id', $tokenId)->delete();
Token expiration add:
If you would like to specify the expiration time of each token independently, you may do so by providing the expiration time as the third argument to the createToken method:
return $user->createToken(
'token-name', ['*'], now()->addWeek()
)->plainTextToken;
A MINI EXAMPLE:
Make controller
php artisan make:controller AuthController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Models\User;
class AuthController extends Controller
{
// Method for user login and issuing a token
public function login(Request $request)
{
$credentials = $request->validate([
'email' => 'required|email',
'password' => 'required'
]);
if (Auth::attempt($credentials)) {
$user = Auth::user();
$token = $user->createToken('API Token ETC')->plainTextToken;
return response()->json([
'message' => 'Login successful',
'token' => $token
], 200);
}
return response()->json([
'message' => 'Invalid credentials'
], 401);
}
// Method to log out the user and revoke the token
public function logout(Request $request)
{
// Revoke all tokens...
$request->user()->tokens()->delete();
return response()->json([
'message' => 'Logged out successfully'
], 200);
}
// Method to get the authenticated user details
public function user(Request $request)
{
return response()->json($request->user());
}
}
Routes\api.php
use App\Http\Controllers\AuthController;
// Public route for login
Route::post('/login', [AuthController::class, 'login']);
// Protected routes
Route::middleware('auth:sanctum')->group(function () {
Route::post('/logout', [AuthController::class, 'logout']);
Route::get('/user', [AuthController::class, 'user']);
});
Send a POST request to /api/login with email and password. If successful, it will return a token.