我之前使用Slim 2创建了一个应用程序,我正在尝试添加Angular。它到目前为止一直很顺利,但我不能再使用我正在使用的CSRF保护,因为Angular正在处理我的所有帖子请求。下面是我工作的Before Middleware。
<?php
namespace Cache\Middleware;
use Exception;
use Slim\Middleware;
class CsrfMiddleware extends Middleware {
protected $key;
public function call() {
$this->key = $this->app->config->get('csrf.key');
$this->app->hook('slim.before', [$this, 'check']);
$this->next->call();
}
public function check() {
if (!isset($_SESSION[$this->key])) {
$_SESSION[$this->key] = $this->app->hash->hash($this->app->randomlib->generateString(128));
}
$token = $_SESSION[$this->key];
if (in_array($this->app->request()->getMethod(), ['POST', 'PUT', 'DELETE'])) {
$submittedToken = $this->app->request()->post($this->key) ?: '';
if (!$this->app->hash->hashCheck($token, $submittedToken)) {
throw new Exception('CSRF token mismatch');
}
}
$this->app->view()->appendData([
'csrf_key' => $this->key,
'csrf_token' => $token
]);
}
}
我知道angular会自动查找名为XSRF-TOKEN的标记,并将其作为X-XSRF-TOKEN添加到标题中。如何修改下面的中间件来编写,读取和比较正确的值。
修改
再次查看并查看超薄文档后,我更改了行:
$submittedToken = $this->app->request()->post($this->key) ?: '';
到此:
$submittedToken = $this->app->request->headers->get('X-XSRF-TOKEN') ?: '';
如果我是对的,这会将$ submittedToken分配给标头中作为X-XSRF-TOKEN传递的值。它使用来自中间件“CSRF令牌不匹配”的消息抛出异常。这感觉就像进步。以下是相关的Angular:
app.controller('itemsCtrl', ['$scope', '$http', function($scope, $http) {
// Initailize object when the page first loads
$scope.getAll = function() {
$http.post('/domain.com/admin/getNames').success(function(data) {
$scope.names = data;
});
}
修改
下面是PHP代码现在的位置。我认为这是有效的。当我在提交表单之前删除cookie或更改$ token的值时,我收到了预期的CSRF错误。我有点担心当我有多个用户时会发生什么。我还没有测试过。根据此修订版,保护措施是否合理?
<?php
namespace Cache\Middleware;
use Exception;
use Slim\Middleware;
class CsrfMiddleware extends Middleware {
protected $key;
public function call() {
$this->key = $this->app->config->get('csrf.key');
$this->app->hook('slim.before', [$this, 'check']);
$this->next->call();
}
public function check() {
// if (!isset($_SESSION[$this->key])) {
if (!isset($_SESSION[$this->key])) {
// $_SESSION[$this->key] = $this->app->hash->hash($this->app->randomlib->generateString(128));
$this->app->setcookie($this->key, $this->app->hash->hash($this->app->randomlib->generateString(128)));
}
// $token = $_SESSION[$this->key];
if(isset($_COOKIE[$this->key])) {
$token = $_COOKIE[$this->key];
}
if (in_array($this->app->request()->getMethod(), ['POST', 'PUT', 'DELETE'])) {
// $submittedToken = $this->app->request()->post($this->key) ?: '';
$submittedToken = $this->app->request->headers->get('X-XSRF-TOKEN') ?: '';
if (!$this->app->hash->hashCheck($token, $submittedToken)) {
throw new Exception('CSRF token mismatch');
}
}
}
}
答案 0 :(得分:0)
来自Angular docs for $http Cross Site Request Forgery (XSRF) Protection:
可以使用配置时$ httpProvider.defaults的xsrfHeaderName和xsrfCookieName属性,运行时的$ http.defaults或每请求配置对象来指定标头的名称。强>
因此,要将它们更改为使用不同的cookie名称/标题名称,请更改这些值。