【问题标题】:REST and Slim 3 : why CSRF check failed with post method?REST 和 Slim 3:为什么使用 post 方法进行 CSRF 检查失败?
【发布时间】:2018-01-15 23:56:55
【问题描述】:

我想在使用 Slim3 创建的 Web 应用程序上添加一个使用 REST API 的用户。 我在应用程序上使用相同的路由来添加用户并且它有效。 但是由于 CSRF 检查失败,由于另一个网站我有“400 错误请求”,因此通过 ajax 请求。 在此请求之前,我使用 GET 方法获取 CSRF 令牌并使用 CSRF 令牌数据构建隐藏输入。然后我在 POST 方法中给出 CSRF 令牌,但它不起作用......我不明白。

谢谢。

Ajax 获取方法:

$.get("https://extranet.exemple.fr/api/token", {})
            .done(function (data, text, jqxhr) {
                if (data.success === true) {
                    $("#csrf_name").val(data.csrf.csrf_name);
                    $("#csrf_value").val(data.csrf.csrf_value);
                }
            })
            .fail(function (jqxhr) {})
            .always(function () {});
            });

Ajax 发布:

var csrfname = $("#csrf_name").val();
var csrfvalue = $("#csrf_value").val();
var objajaxargs = {
                    dataUser: dataUser,
                    csrf_name: csrfname,
                    csrf_value: csrfvalue,
                };
                $.post("https://extranet.exemple.fr/user/add", objajaxargs)
                    .done(function (data, text, jqxhr) {
                        if (data.success === true) {
                            alert("success");
                        }
                    })
                    .fail(function (jqxhr) {})
                    .always(function () {});

在我的容器中

$container["csrf"] = function ($container) {
    return new \Slim\Csrf\Guard();
};

Slim GET 方法

$app->get('/api/token', function (\Slim\Http\Request $request, \Slim\Http\Response $response, $args) use ($app) {

$container = $app->getContainer();
// Generate new token and update request
$request = $container->csrf->generateNewToken($request);
// Build Header Token
$nameKey = $container->csrf->getTokenNameKey();
$valueKey = $container->csrf->getTokenValueKey();
$name = $request->getAttribute($nameKey);
$value = $request->getAttribute($valueKey);
$tokenArray = [
    $nameKey => $name,
    $valueKey => $value
];

$respCSRF["success"] = false;
if (!empty($tokenArray)) {
    $respCSRF["success"] = true;
    $respCSRF["csrf"] = $tokenArray;
}

return $response->withJson($respCSRF);});

超薄 POST 方法

$app->post("/user/add", function (\Slim\Http\Request $request, \Slim\Http\Response $response, $args) use ($app) {

$container = $app->getContainer();
$objBody = $request->getParsedBody();
$objUser = new \App\Models\UserModel($container);

foreach ($objBody["dataUser"] as $key => $value) {
    $objAdherent->$key = $value;
}

$arrJsonResponse = ["success" => false];

if (filter_var($objUser->mail, FILTER_VALIDATE_EMAIL) !== false) {
    $infosAdd = $objUser->addUser();
    if ($infosAdd !== false) {
        $arrJsonResponse["success"] = true;
        return $response->withJson($arrJsonResponse)->withStatus(201);
    }
} 

return $response->withJson($arrJsonResponse)->withStatus(400);});

【问题讨论】:

  • 也许 Ajax 客户端创建了一个CORS preflight request(选项)。你能检查一下吗?
  • @DanielO。 :我以前有这个: $app->options('/{routes:.+}', function ($request, $response, $args) { return $response; }); $app->add(function ($req, $res, $next) { $response = $next($req, $res); return $response ->withHeader('Access-Control-Allow-Origin', '@ 987654322@) ->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization') ->withHeader('Access-Control-Allow-Methods', ' GET, POST'); });
  • 请试试这个中间件(仅用于测试目的):discourse.slimframework.com/t/cors-slim-preflight-request-fails/…
  • 谢谢,但很抱歉这个中间件没有解决我的问题。

标签: php ajax rest slim slim-3


【解决方案1】:

我解决了我的问题。我将 csrf 令牌持久性设置为 true 并且有效!

解决方案:

 /**
 * Init CSRF
 * @return \Slim\Csrf\Guard
 */
$container["csrf"] = function ($container) {
    $guard = new \Slim\Csrf\Guard();
    $guard->setPersistentTokenMode(true);
    return $guard;
};

【讨论】:

  • 如果您的页面非常依赖 AJAX 调用,这是必须的!
猜你喜欢
  • 1970-01-01
  • 2021-04-01
  • 1970-01-01
  • 2011-07-03
  • 1970-01-01
  • 2019-01-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多