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