在twig中,我生成一个csrf标记({{ csrf_token('my_intention') }}
)。
在Javascript中,我用ajax调用一个控制器,实际上用Fetch API(也尝试了Ajax xmlHttpRequest),POST请求。包含请求中传递的令牌的参数名称是'token = abcdef ...'。
AJAX:
var httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = function (data) {
console.log(data);
};
httpRequest.open('POST', el.getAttribute("data-url"));
httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
httpRequest.send(.......);
获取API:
fetch(el.getAttribute('data-url'), {
method: 'post',
headers: {
"Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
},
body: 'token=' + encodeURIComponent(el.getAttribute('data-token'))
}).then(data => data.text()).then(data => {...}
在名为i的控制器操作中,获取作为POST请求中的数据发送的令牌。我在控制器中检查这样的令牌:
$token = $request->request->get('token');
if (!$this->isCsrfTokenValid('my_intention', $token)) {
throw new InvalidCsrfTokenException("error csrf 2");
}
但Symfony说令牌无效。
我不确定,但我认为在会话变量中找不到令牌。在isTokenValid()
$this->storage->hasToken($token->getId())
中返回false。
在浏览器中,如果我直接调用网址,则可以。
在twig中我设置url来调用像这个data-url="{{ path('_check', {'id': transaction.id}) }}"
这样的数据属性,然后我从javascript中读取这个数据属性并将其传递给ajax / fetch函数。
我用jQuery $ .post尝试了ajax(...并且它有效。唯一的区别是Cookie:PHPSESSID ...在请求标头中,jQuery不在我的原始代码上。
我不明白,我的代码出了什么问题?
Symfony 3.1.3
编辑:已解决:我没有在标头请求中传递凭据,因此,Symfony无法找到会话并检查令牌:
fetch(el.getAttribute('data-url'), {
method: 'post',
headers: {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest"
},
body: 'token=' + el.getAttribute('data-token'),
credentials: 'include'
}).then(data => data.text()).then(data => {
答案 0 :(得分:2)