1

当使用“获取”请求调用 url 时,我能够得到很好的响应。

但是,当我使用“发布”请求调用相同的 url 时,我会收到一个“错误请求”。关于为什么会发生这种情况的任何建议/想法?

index.php 文件中的代码:

//GET Request: This works fine!

$app->get('/api/ss20/registration/?', function () use ($app) {
            echo "hello-get";
});


//POST Request: This gives a bad request error!

$app->post('/api/ss20/registration/?', function () use ($app) {
            echo "hello-post";
});

我用来发出获取请求的简单表格:

<form action="api/ss20/registration/" method="get">
  First name: <input type="text" name="fname"><br>
  Last name: <input type="text" name="lname"><br>
  <input type="submit" value="Submit">
</form>

我用来发出发布请求的简单表格:

<form action="api/ss20/registration/" method="post">
  First name: <input type="text" name="fname"><br>
  Last name: <input type="text" name="lname"><br>
  <input type="submit" value="Submit">
</form>

尝试使用 postman / Arc 来模拟请求。并且获取请求工作正常,但不是帖子。

4

2 回答 2

1

400由于缺少CSRF令牌 ,您很可能会收到错误的请求错误。

在 0.3.1 版本中,UserFrosting 将 CSRF 令牌存储在<meta>页面标签内的特殊标签中<head>。例如,如果我查看account/settings页面的源代码,我会看到:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="Update your account settings, including email, display name, and password.">
    <meta name="author" content="Alex Weissman">
    <meta name="csrf_token" content="583caa307d5c1027a8983251f13a3fe994050001d871e329b16599a29858652891a10c48535c6e4be0580c87503f210072ca83c0a45d49c0d0941b5b2536aa15"> 

    <title>UserFrosting | Account Settings</title>
    ...

因此,不知何故,您需要将该值用于csrf_token您的 POST 提交。通常,如果您使用该ufFormSubmit功能提交带有 Javascript 的表单,UserFrosting 会自动执行此操作。

你会注意到这些行:

// Append page CSRF token
var csrf_token = $("meta[name=csrf_token]").attr("content");
serializedData += "&csrf_token=" + encodeURIComponent(csrf_token); 

这些只是csrf_token<meta>标签中获取值并将其附加到表单的数据中。请注意,要调用此函数,您需要确保页面上没有任何 Javascript 错误。否则,大多数浏览器将默认默认为“传统”表单提交,并且 CSRF 令牌不会附加到您的表单中。

如果您确实想以“传统”方式提交表单,则可以将 CSRF 令牌作为隐藏字段直接插入到 Twig 模板中。只需添加

<input type="hidden" name="{{csrf_key}}" value="{{csrf_token}}">

到你的表格。有关UserFrosting 和 CSRF 令牌的更多信息,请点击此处

于 2016-07-23T16:47:58.263 回答
1

我需要修改中间件/CsrfGuard.php 以将 API url 列入白名单

添加了以下 if 语句。它检查对 /api/ss20/registration 的 POST 请求是否被忽略。

if (!(in_array($this->app->request()->getMethod(), array('POST')) && $uri->getPath() == "/api/ss20/registration"))
        {
            if (in_array($this->app->request()->getMethod(), array('POST', 'PUT', 'DELETE')))  {

                 //error_log("\n".date(DATE_RSS)." Inside CSRF Validation",3, "/tmp/php-error.log");

                $userToken = $this->app->request()->post($this->key);
                if ($token !== $userToken) {
                    //error_log("\n".date(DATE_RSS)." About to send halt-400",3, "/tmp/php-error.log");
                    $this->app->alerts->addMessage('danger', 'Invalid or missing CSRF token.');
                    $this->app->halt(400);
                }
            }
}

谢谢@alexw

于 2016-07-26T17:45:17.293 回答