1

我试图在UserFrosting中提交一个简单的表单,作为测试只显示成功消息,没有数据修改。我遵循了第 2 课的指导,但遇到了CSRF 问题:

UserFrosting 返回以下错误:

CSRF 令牌无效或缺失。

我错过了什么?到目前为止,UserFrosting很容易消化 :(

表格:

<form class="form-horizontal" role="form" name="requestDescription" action="{{site.uri.public}}/soap/requests/desc/edit/{{ keyname }}" method="post">
    <div class="form-group">
        <label for="input_group" class="col-md-2 control-label">Name</label>
        <div class="col-md-10">
            <input type="text" id="input_name" class="form-control" name="lgname" placeholder="{{ name }}">
        </div>
    </div>
    <div class="form-group text-center">
        <button type="submit" class="btn btn-success text-center">Update</button>
    </div>
</form>

在树枝文件的底部添加了脚本部分:

<script>
    $(document).ready(function() {
        // Load the validator rules for this form
        var validators = {{validators | raw}};
        ufFormSubmit(
                $("form[name='requestDescription']"),
                validators,
                $("#userfrosting-alerts"),
                function(data, statusText, jqXHR) {
                    // Reload the page on success
                    window.location.reload(true);
                }
        );
    });
</script>

这是控制器的两个功能:

public function soapRequestDescriptionEditPage($keyname){
    if (!$this->_app->user->checkAccess('uri_soap_requests')){
        $this->_app->notFound();
    }
    $requestDetails = $this->soapRequestReadMeta($keyname);

    $schema = new \Fortress\RequestSchema($this->_app->config('schema.path') . "/forms/soap-request-description-edit.json");
    $this->_app->jsValidator->setSchema($schema);

    $this->_app->render('soap/soap-request-description-edit.twig', [
        "name" => $requestDetails['name'],
        "description" => $requestDetails['description'],
        "keyname" => $keyname,
        "validators" => $this->_app->jsValidator->rules()
    ]);
}

public function test(){
    if (!$this->_app->user->checkAccess('uri_soap_requests')) {
        $this->_app->notFound();
    }
    $post = $this->_app->request->post();
    $ms = $this->_app->alerts;
    $requestSchema = new \Fortress\RequestSchema($this->_app->config('schema.path') . "/forms/soap-request-description-edit.json");
    $rf = new \Fortress\HTTPRequestFortress($ms, $requestSchema, $post);
    $ms->addMessageTranslated("success", "Everyone's title has been updated!", $post);
    $rf->sanitize();
    if (!$rf->validate()) {
        $this->_app->halt(400);
    }
    $data = $rf->data();
}   

index.php文件中的条目:

$app->post('/soap/requests/desc/edit/:request_id/?', function () use ($app) {
    $controller = new UF\SoapController($app);
    return $controller->test();
});
$app->get('/soap/requests/desc/edit/:request_id/?', function ($request_id) use ($app) {
    $controller = new UF\SoapController($app);
    return $controller->soapRequestDescriptionEditPage($request_id);
});

最后,架构:

{
  "lgname" : {
    "validators" : {
      "length" : {
        "min" : 1,
        "max" : 150,
        "message" : "The new title must be between 1 and 150 characters long."
      }
    },
    "sanitizers" : {
      "raw" : ""
    }
  }
}
4

2 回答 2

1

从 UserFrosting 4 开始,您应该将隐藏的 CSRF 输入字段显式添加到您的表单中。有一个forms/csrf.html.twig包含这些字段的部分模板,您可以使用 Twig 的include标签插入:

<form class="form-horizontal" role="form" name="requestDescription" action="{{site.uri.public}}/soap/requests/desc/edit/{{ keyname }}" method="post">
    {% include "forms/csrf.html.twig" %}
    <div class="form-group">
        <label for="input_group" class="col-md-2 control-label">Name</label>
        <div class="col-md-10">
            <input type="text" id="input_name" class="form-control" name="lgname" placeholder="{{ name }}">
        </div>
    </div>
    <div class="form-group text-center">
        <button type="submit" class="btn btn-success text-center">Update</button>
    </div>
</form>

对于没有表单的请求(例如,如果它是纯粹用 Javascript 构建的),您可以从全局site.csrf变量中获取 CSRF 令牌名称和值:

var userName = 'luke';
var fieldName = 'lgname';

var data = {
    'value': fieldValue
};

data[site.csrf.keys.name] = site.csrf.name;
data[site.csrf.keys.value] = site.csrf.value;

var url = site.uri.public + '/api/users/u/' + userName + '/' + fieldName;

return $.ajax({
    type: "PUT",
    url: url,
    data: data
}).done(function (response) {
    window.location.reload();
});
于 2017-07-20T05:39:00.553 回答
0

事实证明我的代码很好。页面上有不相关的 javascript 错误影响 UserFrosting 表单处理。修复这些错误允许 UserFrosting 处理表单。

自我注意...养成查看控制台以查找 javascript 错误的习惯 :)

于 2016-11-21T14:29:04.860 回答