Understanding Laravel Sanctum
Tags: laravel, php, package
Published: 2024-03-19 03:07:21

## Stateful APIs

In the world of web development, APIs can be either stateful or stateless. A stateful API is one that remembers the state of interaction between the client and the server. This means that the server stores information about the client's session and can use this information to respond to subsequent requests.  For example, when a user logs into a web application, the server might create a session for that user and store it in a database. The server then sends a session ID to the client, which the client sends back in subsequent requests. The server uses this session ID to look up the session information and determine the user's authentication status, preferences, etc.  

## Laravel and Stateful APIs
Laravel, a popular PHP framework, provides built-in support for handling stateful APIs. It does this through its session management and authentication services. When a user logs in, Laravel starts a session and stores it on the server. Laravel then sends a session cookie to the client. The client sends this cookie back in subsequent requests, allowing Laravel to look up the session and authenticate the user.  

## Laravel Sanctum

Laravel Sanctum is a package that provides a simple way to authenticate users in your Laravel applications. It was designed to provide a simple way to authenticate SPAs (Single Page Applications), mobile applications, and simple, token-based APIs.  Sanctum does this by providing a simple, lightweight authentication system that uses Laravel's built-in cookie-based session authentication services for SPAs and token-based authentication for APIs.  

## Laravel Passport
Laravel Passport is another package for API authentication. It provides a full OAuth2 server implementation for your Laravel application. This means that it allows your application to issue access tokens that can be used to authenticate API requests.  Passport is more feature-rich than Sanctum and is a good choice if you need to implement OAuth2 authentication. However, it can be overkill if you just need a simple way to authenticate users.  

## OAuth2 and JWT
OAuth2 is an authorization framework that enables applications to obtain limited access to user accounts on an HTTP service. It works by issuing access tokens to third-party applications by an authorization server with the approval of the resource owner.  JWT (JSON Web Tokens) is a compact, URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is used as the payload of a JSON Web Signature (JWS) structure or as the plaintext of a JSON Web Encryption (JWE) structure, enabling the claims to be digitally signed or integrity protected with a Message Authentication Code (MAC) and/or encrypted. While OAuth2 can use JWT as a token format, JWT itself is not tied to OAuth2. It can be used in a variety of other contexts where there's a need to securely pass claims between two parties.  

## Laravel Sanctum and JWT
Laravel Sanctum and JWT (JSON Web Tokens) are both used for authentication, but they work in different ways and serve different purposes. 

#### Sanctum Token:
Laravel Sanctum provides a simple way to authenticate users and issue API tokens. These tokens are typically stored in a database and are associated with the user's session. Sanctum tokens are stateful, meaning they maintain a session and keep track of the user's state on the server. Sanctum tokens are typically used for SPAs (Single Page Applications), mobile applications, and simple, token-based APIs.

#### JWT Token:
JWT, on the other hand, is a standard for token-based authentication that is not tied to any specific authentication framework. JWTs are stateless, meaning they do not maintain a session or keep track of the user's state on the server. Instead, they encode the user's information directly into the token itself. This information can be decoded and verified by the server on each request. JWTs are often used in scenarios where you need to ensure the integrity of the information contained within the token, such as in distributed systems.  In summary, the main difference between Sanctum tokens and JWTs is that Sanctum tokens are stateful and tied to a user's session, while JWTs are stateless and encode the user's information directly into the token.

## Implement Laravel Sanctum with Basic Authentication
Now we'll walk through the process of implementing Laravel Sanctum with basic authentication. 

#### Installation
First, you need to install Sanctum via Composer:
`composer require laravel/sanctum`
Next, publish the Sanctum configuration and migration files:
`php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"`
Then, run your database migrations:
`php artisan migrate`

#### User Model
In your `App\Models\User` model, use the `Laravel\Sanctum\HasApiTokens` trait:

```php
<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens;

    // ...
}
```

#### Routes and Controllers

Now, let's create the routes and controllers for user registration and login.  In `routes/api.php`, add the following routes:

```php
<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Api\AuthController;

Route::post('/register', [AuthController::class, 'register']);
Route::post('/login', [AuthController::class, 'login']);
```
Then, create `app/Http/Controllers/Api/AuthController.php`:

```php
<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;

class AuthController extends Controller
{
    public function register(Request $request)
    {
        $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:8',
        ]);

        $user = User::create([
            'name' => $request->name,
            'email' => $request->email,
            'password' => Hash::make($request->password),
        ]);

        return response()->json([
            'user' => $user,
            'token' => $user->createToken('token-name')->plainTextToken,
        ], 201);
    }

    public function login(Request $request)
    {
        $request->validate([
            'email' => 'required|string|email',
            'password' => 'required|string',
        ]);

        $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 response()->json([
            'user' => $user,
            'token' => $user->createToken('token-name')->plainTextToken,
        ]);
    }
}
```

#### Authenticate requests:
To authenticate a request, the client should send the token in the Authorization header.

```
Authorization: Bearer <token>
```

#### Protect routes:
You can protect your routes using Sanctum's middleware. Any route protected by this middleware will require a valid API token.

```php
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});
```

#### Revoke tokens:
When a user logs out, you can revoke their tokens.

```php
public function logout(Request $request)
{
    $request->user()->tokens()->delete();

    return response()->json('Logged out successfully');
}
```
This is a basic example of how you might use Laravel Sanctum with basic authentication. For more detailed information, you should refer to the [Laravel Sanctum documentation](https://laravel.com/docs/master/sanctum).

## Conclusion
Laravel Sanctum provides a simple and flexible way to handle API token authentication in Laravel applications. It offers a range of features that make it easy to manage and secure API tokens, from issuing and revoking tokens to assigning token abilities and protecting routes.
However, as with any security-related feature, it's important to use Laravel Sanctum responsibly. This includes securely storing tokens on the client side, handling token expiration and renewal, limiting token permissions, and transmitting tokens over secure channels. Regular audits of token usage can also help detect potential security issues.
By following these best practices and making full use of the features provided by Laravel Sanctum, you can build secure and robust API authentication for your Laravel applications.