Securing Your Laravel API: Hiding Sensitive Attributes from JSON Output

Securing Your Laravel API: Hiding Sensitive Attributes from JSON Output

When building APIs with Laravel, it's crucial to control what data is exposed to the client. Laravel's Eloquent ORM provides an elegant way to hide sensitive attributes when converting models to arrays or JSON. Let's explore how to implement this feature effectively.

The $hidden Property

The simplest way to hide attributes is by using the $hidden property in your Eloquent model:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = ['password', 'remember_token'];
}

In this example, the password and remember_token fields will be excluded from the model's array and JSON representations.

Hiding Relationships

You can also hide entire relationships by adding the relationship's method name to the $hidden array:

protected $hidden = ['password', 'remember_token', 'secretDocuments'];

The $visible Property

Alternatively, you can use the $visible property to define an "allow list" of attributes that should be included in the model's array and JSON representation:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * The attributes that should be visible in arrays.
     *
     * @var array
     */
    protected $visible = ['first_name', 'last_name', 'email'];
}

This approach is particularly useful when you want to expose only a few attributes and hide everything else.

Dynamic Attribute Visibility

Sometimes you might need to change the visibility of attributes dynamically. Laravel provides methods to do this:

// Hide attributes
$user->makeHidden(['attribute', 'another_attribute']);

// Make attributes visible
$user->makeVisible(['attribute', 'another_attribute']);

These methods are useful when you need different attribute visibility in different contexts.

Practical Example

Let's consider a scenario where we have a User model with some sensitive information:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    protected $hidden = ['password', 'credit_card_number'];
    
    protected $visible = ['id', 'name', 'email'];

    public function getPublicProfileAttribute()
    {
        return $this->only($this->visible);
    }

    public function getAdminProfileAttribute()
    {
        return $this->makeVisible(['created_at', 'updated_at'])->toArray();
    }
}

In this example, we've defined a basic set of hidden and visible attributes. We've also added two accessor methods that provide different views of the user data based on the context.

When using this model:

$user = User::find(1);

// For public API
return response()->json($user->public_profile);

// For admin panel
return response()->json($user->admin_profile);

This approach allows you to maintain fine-grained control over your data exposure while keeping your controller logic clean.

By leveraging Laravel's attribute hiding features, you can ensure that sensitive data is never accidentally exposed through your API. This not only enhances the security of your application but also helps in creating cleaner, more focused API responses.

If this guide was helpful to you, subscribe to my daily newsletter and give me a follow on X/Twitter. It helps a lot!

Subscribe to Harris Raftopoulos

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe