Как вызвать средство доступа Eloquent после извлечения данных - PullRequest
0 голосов
/ 21 февраля 2019

Цель

Я хочу иметь возможность скрывать свои идентификаторы при отправке ответов JSON.

Я попытался

Создание аксессора , как показано ниже:

public function getIdAttribute()
{
    return Crypt::encrypt($this->attributes['id']);
}

Но это разрушает мои отношения, потому что (я узнал с этим) аксессор запускается до запроса ...

Вопрос

Можно ли как-то сказать Eloquent на запуск средства доступа после извлечения результата?

Ответы [ 3 ]

0 голосов
/ 21 февраля 2019

Найден альтернативный способ достичь того, что я хотел, используя Макросы ответа :

app / Providers / AppServiceProvider.php

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Response;
use Crypt;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        JsonResponse::macro('secured', function () {
            $data = json_decode(json_encode(JsonResponse::getData()), $toArray = true);

            array_walk_recursive($data, function(&$value, $key) {
                if ($key === 'id') {
                    $value = Crypt::encrypt($value);
                }
            });

            return $data;
        });
    }

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

Затем на любом из ваших контроллеров:

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Post;

class PostController extends Controller
{
    public function index(Request $request)
    {
        if ($request->wantsJson() || $request->ajax()) {
            return response()->json(Post::all())->secured();
        }
    }
}

Предупреждение

В моей схеме базы данных предполагается, что все первичные ключи имеют имя "id".Помните об этом, если вы копируете / вставляете это!

0 голосов
/ 22 февраля 2019

Я вижу здесь 2 варианта ..

1.

Вместо того, чтобы выставлять свой идентификатор, вы можете добавить поле uuid в вашу таблицу, учитывая, что, вероятно, вы хотите, чтобы потребители API моглизапросить / обновить / удалить отдельные объекты, которые вам необходимо идентифицировать?

Таким образом, у вас все еще есть уникальный идентификатор для ваших объектов, но его невозможно угадать.

2.

Если вы не хотите добавлять дополнительные поля и все равно хотите зашифровать идентификатор, почему бы не использовать вместо этого объект Resource Response?

Это позволит вам настроить ответ перед его возвратом.

См .: https://laravel.com/docs/5.7/eloquent-resources#resource-responses

Итак, в вашем контроллере:

public function index(Request $request)
{
    $posts = Post::all();

    return new PostResourceCollection($posts);
}

PostResourceс шифрованием id

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\Resource;
use Crypt;

class PostResource extends Resource
{
    public function toArray($request)
    {
        return [
            'id' => Crypt::encrypt($this->id]),
            'x' => $this->x,
            'y' => $this->y,
        ];
    }
}

PostResourceCollection, который просто вызывает коллекцию на PostResource

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\ResourceCollection;

class PostResourceCollection extends ResourceCollection
{
    public function toArray($request)
    {
        return PostResource::collection($this->collection);
    }
}
0 голосов
/ 21 февраля 2019

Ваши методы доступа никогда не должны выполнять никаких действий с вашими свойствами.Вместо этого после использования метода, то есть получения значения идентификатора, необходимо использовать шифр.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...