目标
我希望能够在发送JSON响应时混淆我的ID。
我尝试了
创建如下的accessor:
public function getIdAttribute()
{
return Crypt::encrypt($this->attributes['id']);
}
但是这破坏了我的关系,因为(我从中学到的)访问器在查询之前就已经运行了。
问题
是否有任何方法告诉Eloquent在结果被拉出后触发访问器?
答案 0 :(得分:0)
您的访问器方法永远不要对属性执行任何操作。相反,使用该方法后(即获得ID的值),必须使用encrypyt。
答案 1 :(得分:0)
找到了使用Response macros来实现我的预期的另一种方法:
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”。如果您复制/粘贴此内容,请记住这一点!
答案 2 :(得分:0)
我在这里看到2个选项。
1。
考虑到您可能希望API使用者能够请求/更新/删除您需要标识的单个对象,您可以向表中添加uuid字段,而不是公开您的ID?
这样,您仍然可以为对象提供唯一的标识符,但是无法猜测。
2。
如果您不想添加额外的字段并且想对ID进行加密,为什么不使用资源响应对象呢?
这将使您可以在返回之前自定义响应。
请参阅:https://laravel.com/docs/5.7/eloquent-resources#resource-responses
因此在您的控制器中:
public function index(Request $request)
{
$posts = Post::all();
return new PostResourceCollection($posts);
}
具有ID加密的PostResource
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);
}
}