Skip to main content
The Laravel Blog API uses custom middleware to protect endpoints that require authentication. The ApiAuthMiddleware validates JWT tokens before allowing access to protected routes.

ApiAuthMiddleware implementation

The middleware checks for a valid JWT token in the Authorization header:
app/Http/Middleware/ApiAuthMiddleware.php
class ApiAuthMiddleware
{
    public function handle($request, Closure $next) {
        $token = $request->header('Authorization');
        $jwtAuth = new \JwtAuth();
        $checkToken = $jwtAuth->checkToken($token);

        if($checkToken) {
            return $next($request);
        }
        else {
            $data = array(
                'code' => 400,
                'status' => 'error',
                'message' => 'El usuario no esta identificado.'
            );
            return response()->json($data, $data['code']);
        }
    }
}

How it works

1

Extract token

The middleware retrieves the JWT token from the Authorization header:
$token = $request->header('Authorization');
2

Validate token

It uses the JwtAuth helper to validate the token:
$jwtAuth = new \JwtAuth();
$checkToken = $jwtAuth->checkToken($token);
3

Allow or deny

If valid, the request proceeds. If invalid, it returns a 400 error:
if($checkToken) {
    return $next($request); // Continue to controller
}
else {
    return response()->json([
        'code' => 400,
        'status' => 'error',
        'message' => 'User is not authenticated.'
    ], 400);
}
The middleware is registered in your application as api.auth and can be applied to routes or controllers.

Applying middleware to controllers

You can apply middleware in the controller constructor to protect specific methods:
The PostController protects write operations while allowing public read access:
app/Http/Controllers/PostController.php
public function __construct() {
    $this->middleware('api.auth', ['except' => [
        'index',
        'show',
        'getImage',
        'getPostsByCategory',
        'getPostsByUser',
    ]]);
}
Protected endpoints (require authentication):
  • store() - Create new post
  • update() - Update existing post
  • destroy() - Delete post
  • upload() - Upload post image
Public endpoints (no authentication):
  • index() - List all posts
  • show() - Get single post
  • getImage() - Retrieve post image
  • getPostsByCategory() - List posts by category
  • getPostsByUser() - List posts by user
Routes not listed in the except array will require valid JWT authentication.

Using middleware in protected methods

Once a route passes middleware validation, you can safely extract user information from the token:
app/Http/Controllers/PostController.php
public function store(Request $request) {
    // Get authenticated user from token
    $jwtAuth = new JwtAuth();
    $token = $request->header('Authorization', null);
    $user = $jwtAuth->checkToken($token, true);

    // Create post with user ID from token
    $post = new Post();
    $post->user_id = $user->sub;
    $post->category_id = $params->category_id;
    $post->title = $params->title;
    $post->content = $params->content;
    $post->image = $params->image;
    $post->save();
}

Helper method for getting user identity

Many controllers use a helper method to extract user identity:
app/Http/Controllers/PostController.php
private function getIdentity(Request $request) {
    $jwtAuth = new JwtAuth();
    $token = $request->header('Authorization', null);
    $user = $jwtAuth->checkToken($token, true);
    return $user;
}

// Usage in controller methods
public function update($id, Request $request) {
    $user = $this->getIdentity($request);

    // Ensure user can only update their own posts
    $post = Post::where('id', $id)
        ->where('user_id', $user->sub)
        ->first();

    if(!empty($post)) {
        $post->update($params_array);
    }
}
This pattern ensures users can only modify their own content.

Authorization patterns

The API implements owner-based authorization:
public function update($id, Request $request) {
    $user = $this->getIdentity($request);

    // Only fetch posts belonging to authenticated user
    $post = Post::where('id', $id)
        ->where('user_id', $user->sub)
        ->first();

    if(!empty($post) && is_object($post)) {
        $post->update($params_array);
    }
}
By including ->where('user_id', $user->sub) in queries, the API ensures:
  • Users can only update or delete their own posts
  • Prevents unauthorized access to other users’ content
  • No additional authorization logic needed
  • Database-level security

Error responses

When authentication fails, the middleware returns a consistent error response:
{
  "code": 400,
  "status": "error",
  "message": "El usuario no esta identificado."
}
Common authentication failures:
Request sent without Authorization header:
curl -X POST "https://api.example.com/api/post"
# Returns 400 error

Manual token validation

Some controllers manually validate tokens instead of using middleware:
app/Http/Controllers/UserController.php
public function update(Request $request) {
    $token = $request->header('Authorization');
    $jwtAuth = new \JwtAuth();
    $checkToken = $jwtAuth->checkToken($token);

    if($checkToken) {
        // Process update
        $user = $jwtAuth->checkToken($token, true);
        $user_update = User::where('id', $user->sub)->update($params_array);
    }
    else {
        $data = array(
            'code' => 400,
            'status' => 'error',
            'message' => 'El usuario no esta identificado.'
        );
        return response()->json($data, $data['code']);
    }
}
Using middleware in the constructor is preferred over manual validation as it’s more maintainable and follows Laravel conventions.

Testing protected endpoints

To test protected endpoints, you need a valid JWT token:
1

Login to get token

curl -X POST "https://api.example.com/api/user/login" \
  -H "Content-Type: application/json" \
  -d '{"json":"{\"email\":\"[email protected]\",\"password\":\"password123\"}"}'
2

Copy the JWT token

The response will contain your JWT token:
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
3

Use token in requests

curl -X POST "https://api.example.com/api/post" \
  -H "Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." \
  -H "Content-Type: application/json" \
  -d '{"json":"{\"title\":\"My Post\",\"content\":\"Content here\"}"} '

Next steps

Authentication

Deep dive into JWT token generation and validation

Protected endpoints

Explore endpoints that require authentication

Build docs developers (and LLMs) love