Developer Snippet Diary

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.

  1. 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
  2. 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.

 

Posted by: R GONDAL
Email: rizikmw@gmail.com