【问题标题】:Securing internal API endpoint with Laravel使用 Laravel 保护内部 API 端点
【发布时间】:2020-02-13 06:34:05
【问题描述】:

我有一个网络应用程序,用户可以在其中上传文档。

一个用户可以上传许多文档 (hasMany)。

我有下面的Vue 文件,它获取我的内部 API 以从上传的文档中获取信息。以下是我正在使用的方法:

ShowDocument.Vue

getDocument: function (documentId) {
    axios.get('/api/documents/' + documentId).then((response) => {
        this.document = response.data.document;
    }).catch(error => {
        console.log(error);
    })

},

在我的routes/api.php 文件中,我定义了以下路线:

Route::apiResource('documents', 'Api\DocumentsController')->middleware('ajax')->only(['show']);

如您所见,我有一个名为ajax 的自定义中间件。这确保只接受对 API 端点的 AJAX 请求:

app\Http\Middleware\RequestIsAjax.php

public function handle($request, Closure $next)
{
    if (! $request->ajax())
        return abort(403);
    return $next($request);
}

此外,DocumentsController 看起来像这样:

public function show($id)
{
    $document = Document::findOrFail($id);

    return response()->json([
        'document' => $document,
    ], 200);
}

到目前为止一切顺利。现在,我的问题是 - 此 API 端点仅在内部使用(目前),但作为用户,我可以轻松查看其他用户文档的信息,只需发送 AJAX 请求到:

/api/documents/<documentID>

然后简单地替换为另一个数字。

我的问题是,如何防止这种情况并确保只有用户才能查看自己的文档?

【问题讨论】:

  • 在您的控制器中添加检查。
  • 更好的是添加一个where 条件,该条件自动从模型的引导方法中附加,您还可以添加当前已验证的user_idwhere
  • @vivek_23 很有趣。你介意提供一个例子吗?我不确定如何合并它,因为 axios.get() 仅包含文档 ID。
  • 您将在后端而不是前端执行此操作。你能告诉我你如何在你的应用程序中获取 user_id 吗?另外,Document 在 DB 表中有 user_id 列吗?
  • 是的 Document 有一个 user_id 列。在正常情况下,我只会定义一个策略并执行return $user-&gt;id === $document-&gt;user_id 之类的操作

标签: php laravel vue.js vuejs2 axios


【解决方案1】:

您可以添加额外的检查。它可以像这样简陋:

public function show($id)
{
    $document = Document::findOrFail($id);

    if ($document->user_id !== auth()->id())
    {
        return response()->json([
            'message' => 'You are not allowed to see this document',
        ], 403);
    }

    return response()->json([
        'document' => $document,
    ], 200);
}

或者,您也可以在查找文档时执行此操作(因为您似乎没有使用模型绑定),所以这也应该有效:

public function show($id)
{
    $document = Document::where('user_id', auth()->id)->find($id);

    if ($document)
    {
        return response()->json([
            'message' => "The document does not exist or you are not allowed to see it.",
        ], 404);
    }

    return response()->json([
        'document' => $document,
    ], 200);
}

再一次,您不仅可以在控制器中实现它,还可以在中间件、表单请求等中实现它。

【讨论】:

    猜你喜欢
    • 2015-08-07
    • 2013-11-28
    • 2016-08-22
    • 2012-02-12
    • 1970-01-01
    • 1970-01-01
    • 2019-02-20
    • 2020-11-30
    • 2019-12-25
    相关资源
    最近更新 更多