Userfrosting:开始工作,但不是Post

时间:2016-07-23 13:02:44

标签: slim userfrosting

使用' Get'来调用网址时请求,我能够得到答复。

然而,当我使用' Post'来呼叫相同的网址时请求,我收到了一个错误的请求'。关于为什么会发生这种情况的任何建议/想法?

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模拟请求。获取请求工作正常,但不是帖子。

2 个答案:

答案 0 :(得分:1)

由于缺少CSRF令牌,您最有可能收到400错误请求错误。

在版本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 and CSRF tokens here的更多信息。

答案 1 :(得分:1)

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

添加了以下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