Laravel Encryptable Trait

Note: This post is out of date, Laravel can now do this encryption out of the box without a trait. Please check the update.

In our main repo, we have a lot of MySQL fields that are required to be encrypted. Instead of littering our controllers and views with crypt/decrypt, we decided to just use a simple trait to handle both of those. This allows us to just save data and it will auto encrypt and within the view just calling {{ $model->encrypted }} for output.

Currently running on Laravel 7.

Drop the following into your App\Traits directory

Laravel Encryptable Trait

<?php

namespace App\Traits;

use Crypt;

trait Encryptable
{
    /**
     * Get a models attribute on select
     *
     * @param string $key
     * @return mixed
     */
    public function getAttribute($key)
    {
        $value = parent::getAttribute($key);
        if (in_array($key, $this->encryptable)) {
            try {
                $value = Crypt::decrypt($value);
            } catch (\Exception $e) {
                return $value;
            }
        }
        return $value;
    }

    /**
     * Set a models attribute on save
     *
     * @param string $key
     * @param string|null $value
     * @return mixed
     */
    public function setAttribute($key, $value)
    {
        if (is_null($value)) {
            $value = "";
        }
        if (in_array($key, $this->encryptable) && $value != "") {
            $value = Crypt::encrypt($value);
        }
        return parent::setAttribute($key, $value);
    }
}

Usage:

<?php

use App\Traits\Encryptable;

class ApiWebHook extends Model
{
    use Encryptable;

    protected $encryptable = [
        'username',
        'api_key'
    ];
}

Did you find this article valuable?

Support Guy Warner by becoming a sponsor. Any amount is appreciated!