2

我正在使用 Encryptable 特征来加密 Room 模型的数据。

RoomController (/rooms)返回解密后的数据,但 ApiRoomController (/api/rooms)不返回。我怎样才能让它返回解密的数据?

可加密特征

trait Encryptable
{
    public function getAttribute($key)
    {
        $value = parent::getAttribute($key);
        if (in_array($key, $this->encryptable) && $value !== '' && $value !== null ) {
            $value = Crypt::decrypt($value);
        }

        return $value;
    }

    public function setAttribute($key, $value)
    {
        if (in_array($key, $this->encryptable)) {
            $value = Crypt::encrypt($value);
        }

        return parent::setAttribute($key, $value);
    }
}

RoomController 索引函数

public function index()
{
    $rooms = Room::select('id', 'name')->get()->sortBy('name')->values()->all();

    return view('rooms.index')->withRooms($rooms);
}

ApiRoomController 索引函数

public function index()
{
    $rooms = Room::select('id', 'name')->get()->sortBy('name')->values()->all();

    return response()->json($rooms);
}
4

2 回答 2

4

我找到了一种使用API 资源的方法:

php artisan make:resource Rooms --collection

然后在你的app/Http/Resources/Rooms.php文件中:

public function toArray($request)
{
    return [
        'id'   => $this->id,
        'name' => $this->name,
        // more fields here
    ];
}

然后在你的ApiRoomController.php文件中:

use App\Http\Resources\Rooms;


public function index()
{
    $rooms = Room::select('id', 'name')->get()->sortBy('name')->values()->all();

    return Rooms::collection($rooms);
}
于 2019-05-09T20:19:00.830 回答
2

似乎@emotality 已经为此提出了一个很好的解决方案......

但是,这不能按预期工作的原因是因为底层模型的toArray()/toJson()方法没有调用getAttribute()您的 trait 中的方法。

这很重要,因为该response()->json()方法映射给定的集合并toJson()在每个模型上调用该方法,以便为响应做好准备。

因此,您也可以通过覆盖toArray模型中的方法来解决此问题。

class Room extends Model
{
    use Encryptable;

    public function toArray()
    {
        return [
            'id'   => $this->id,
            'name' => $this->name,
            // ...
        ];
    }
}

于 2019-05-09T21:05:24.627 回答