【问题标题】:How to make a post request to a protected Laravel API route with JavaScript using the API token?如何使用 API 令牌通过 JavaScript 向受保护的 Laravel API 路由发出发布请求?
【发布时间】:2020-08-18 00:41:45
【问题描述】:

说明

我有一张表,我用 JavaScript 从复选框中收集值。此值应发送到 Laravel 后端中受保护的 API 路由。 我使用标准的 Laravel 身份验证设置(开箱即用)。

问题

我必须通过 JavaScript 发布请求发送什么以进行身份​​验证,我该怎么做?我可以在标题中添加身份验证令牌或类似的东西吗? 目前我得到了回复:

“此操作未经授权”。

exception: "Symfony\\Component\\HttpKernel\\Exception\\AccessDeniedHttpException"

编辑

在我目前的研究阶段,api 令牌似乎是我的案例的简单解决方案。但我不知道如何将 api 令牌附加到 JavaScript 发布请求。

这就是用于收集将值存储在对象中的 JavaScript 函数。

import SaveData from "../api/SaveData";

export default async function SaveMultipleReports() {
const table = document.getElementById("reports-dashboard");
const rows = table.querySelectorAll("div[class=report-tr]");

let reports = [];
for (const row of rows) {
    const checkbox_visible = row.querySelector("input[name=visible]")
        .checked;
    const checkbox_slider = document.querySelector(
        "input[name=show_in_slider]"
    ).checked;

    const report = {
        id: row.id,
        visible: checkbox_visible,
        show_in_slider: checkbox_slider
    };
    reports.push(report);
}

console.log(reports);
const response = await SaveData("/api/reports/update", reports);
console.log(response);
}

这就是SavaData 函数:

export default async function SaveData(api, data) {
    const token = document
        .querySelector('meta[name="csrf-token"]')
        .getAttribute("content");
    const url = window.location.origin + api;
    const response = await fetch(url, {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
            "X-CSRF-TOKEN": token,
            Accept: "application/json"
        },
        body: JSON.stringify(data)
    });

    const result = await response.json();
    return result;
}

这就是api.php 中的那一行:

Route::middleware("can:administration")->post("reports/update", "ReportsController@UpdateAll");

整个仓库是here

提前感谢您的时间:)

编辑 2

现在我在没有 JavaScript 的情况下管理它。输入所有值,我想更新表单并为每个对象的 ID 加载隐藏输入(之后控制器需要 ID)。 感谢this post

{!! Form::open(["route" => ["admin.reports.multiupdate"], "method" => "PUT", "class" => "report-table"]) !!}

... // some HTML

@foreach ($reports as $report)
<div class="report-tr">
  <input type="hidden" name="reports[{{$loop->index}}][id]" value="{{$report->id}}">
  <div class="td-name">
    <p class="td-text">{{$report->name}}</p>
  </div>
  <div class="td-flex">{{$report->body}}</div>
  <div class="tr-wrapper">
    <div class="checkbox-visible">
      <div class="checkbox-container">
        <input class="checkbox" type="checkbox" name="reports[{{$loop->index}}][visible]" value="1" checked>
        <span class="checkmark"></span>
      </div>
      <label class="table-label" for="visible">Sichtbar</label>
    </div>
    <div class="checkbox-slider">
      <div class="checkbox-container">
        <input class="checkbox" type="checkbox" name="reports[{{$loop->index}}][show_in_slider]" value="1"
          {{($report->show_in_slider == 1 ? "checked" : "")}}>
        <span class="checkmark"></span>
      </div>
      <label class="table-label" for="show_in_slider">Im Slider</label>
    </div>
    <div class="td-buttons">

... 

@endforeach
<button class="floating-save">
  @svg("saveAll", "saveAll")
</button>
{!! Form::close() !!}

还有来自控制器的 sn-p:

public function MultipleUpate(ReportUpdate $request)
  {
     $reports = $request->input("reports");

foreach ($reports as $row) {
  $report = Report::find($row["id"]);

  // giving the checkbox 0, if it isn't checked

  $isVisible = isset($row["visible"]) ? 1 : 0;
  $inSlider = isset($row["show_in_slider"]) ? 1 : 0;

  $report->visible = $isVisible;
  $report->show_in_slider = $inSlider;

  $report->new = false;

  if ($report->save()) {
    $saved = true;
  }
}

if ($saved == true) {
  $request->session()->flash("success",  "Änderungen gespeichert!");
} else {
  $request->session()->flash("error",  "Das hat nicht geklappt!");
}

return back();

ReportUdpate 函数只包含:

public function authorize()
  {
    return true;
  }

  public function rules()
  {
    return [
      "visible" => "nullable",
      "show_in_slider" => "nullable"
    ];
  }

【问题讨论】:

    标签: javascript laravel authentication post protected


    【解决方案1】:

    您说的是身份验证,但使用的是授权中间件。两者是有区别的。

    在这里阅读:https://medium.com/datadriveninvestor/authentication-vs-authorization-716fea914d55

    话虽如此,您正在寻找的是一种身份验证中间件,可以保护您的路由免受未经身份验证的用户的攻击。 Laravel 提供了一个名为 Authenticate 的中间件,用于此特定目的。

    把你的路线改成这样:

    Route::middleware("auth")->post("reports/update", "ReportsController@UpdateAll");
    

    【讨论】:

    • 感谢您的回答 :) 据我所知,授权和身份验证之间的区别对我来说很清楚。如您所见,我添加了(can:administration) 中间件。这限制了管理员用户对路由的访问。正如我所写,问题是如何在 JS 发布请求中附加正确的令牌。那是因为我设置了标准的 Laravel 身份验证设置并且不使用 JS(React/Vue)前端管理身份验证。目前我“解决”了上面Edit2中写的问题。
    • 如果有帮助,您可以将令牌添加到 axios 通用标头中。
    猜你喜欢
    • 2016-02-16
    • 2018-12-16
    • 2016-01-21
    • 2017-12-25
    • 2021-05-04
    • 2022-01-09
    • 2017-09-13
    • 2019-11-22
    • 2019-02-19
    相关资源
    最近更新 更多