Laravel API Authentication Using Sanctum

Laravel Sanctum provides a featherweight authentication system for SPAs (single page applications), mobile applications, and simple, token-based APIs.


Introduction#

Laravel Sanctum provides a featherweight authentication system for SPAs (single page applications), mobile applications, and simple, token-based APIs. Sanctum allows each user of your application to generate multiple API tokens for their account. These tokens may be granted abilities/scopes which specify which actions the tokens are allowed to perform.


Installation#

  1. You may install Laravel Sanctum via the install:api Artisan command:
  2. php artisan install:api
  3. Sanctum allows you to issue API tokens / personal access tokens that may be used to authenticate API requests to your application. When making requests using API tokens, the token should be included in the Authorization header as a Bearer token.
  4. To begin issuing tokens for users, your User model should use the Laravel\Sanctum\HasApiTokens trait:

    use Laravel\Sanctum\HasApiTokens;
    
    class User extends Authenticatable
    {
      use HasApiTokens;
    }
  5. install:api command will add routes/api.php file. That should be included in the bootstrap/app.php file inside withRouting as below:
  6. return Application::configure(basePath: dirname(__DIR__))
      ->withRouting(
        web: __DIR__ . '/../routes/web.php',
        api: __DIR__ . '/../routes/api.php', // Add this if not added by install:api
        commands: __DIR__ . '/../routes/console.php',
        health: '/up',
      );
  7. Finally, you should run your database migrations. Sanctum will create one database table in which to store API tokens:
  8. php artisan migrate
  9. Next, if you plan to utilize Sanctum to authenticate an SPA, please refer to the SPA Authentication section of this documentation.

Sanctum Authentication#

We'll create simple user authentication methods via Laravel Sanctum below.

  1. Create Route: Create routes into routes/api.php that point to AuthController:
  2. <?php
    
    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Route;
    use App\Http\Controllers\AuthController;
    
    // Open Routes
    Route::post('/register', [AuthController::class, 'register']);
    Route::post('/login', [AuthController::class, 'login']);
    
    // Protected Routes
    Route::group(['middleware' => 'auth:sanctum'], function () {
      Route::get('/profile', [AuthController::class, 'profile']);
      Route::get('/logout', [AuthController::class, 'logout']);
    });
  3. Create Controller: Now, we have to create a controller that handles all API requests. Follow below artisan command to create a new controller:
  4. php artisan make:controller AuthController
  5. Register User: We'll implement a simple method to register a user:
  6. <?php
    
    namespace App\Http\Controllers;
    
    use App\Http\Controllers\Controller;
    use Illuminate\Http\Request;
    use App\Models\User;
    
    class AuthController extends Controller
    {
      // POST [name, email, password]
      public function register(Request $request)
      {
        // Validation
        $request->validate([
          "name" => "required|string",
          "email" => "required|string|email|unique:users",
          "password" => "required|confirmed" // password_confirmation
        ]);
    
        // Create User
        User::create([
          "name" => $request->name,
          "email" => $request->email,
          "password" => bcrypt($request->password)
        ]);
    
        return response()->json([
          "status" => true,
          "message" => "User registered successfully",
          "data" => []
        ]);
    
      }
    }

    TEST register user API using postman

    register
  7. Login User: In the same file AuthController.php, create a simple login method that generates API token via sanctum:
  8. <?php
    
    namespace App\Http\Controllers\Api;
    
    use App\Http\Controllers\Controller;
    use Illuminate\Http\Request;
    use App\Models\User;
    use Illuminate\Support\Facades\Hash;
    
    class AuthController extends Controller
    {
      public function login(Request $request)
      {
        // POST [email, password]
        // Validation
        $request->validate([
          'email' => 'required|email|string',
          'password' => 'required'
        ]);
    
        // Email check
        $user = User::where("email", $request->email)->first();
    
        if (!empty($user)) {
          // User exists
          if (Hash::check($request->password, $user->password)) {
            // Password matched
            $token = $user->createToken("myAccessToken")->plainTextToken;
    
            return response()->json([
              "status" => true,
              "message" => "Login successful",
              "token" => $token,
              "data" => []
            ]);
          } else {
            return response()->json([
              "status" => false,
              "message" => "Password didn't match",
              "data" => []
            ]);
          }
        } else {
          return response()->json([
            "status" => false,
            "message" => "Invalid Email value",
            "data" => []
          ]);
        }
      }
    }

    TEST Login user API using postman

    login
  9. Get User Profile: In the same file AuthController.php, create a simple method to get the user's profile details:
  10. public function profile()
    {
      $userData = auth()->user();
    
      return response()->json([
        "status" => true,
        "message" => "Profile information",
        "data" => $userData,
        "id" => auth()->user()->id
      ]);
    }

    TEST get user API using postman

    profile
  11. Logout User: In the same file AuthController.php, create a simple method to revoke the token from the user:
  12. public function logout()
    {
      auth()->user()->tokens()->delete();
    
      return response()->json([
        "status" => true,
        "message" => "User Logged out successfully",
        "data" => []
      ]);
    }

    TEST logout user API using postman

    logout