// src/Application.php
// ...
use Cake\Http\Middleware\CsrfProtectionMiddleware;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
class Application extends BaseApplication
{
// ...
public function middleware($middleware)
{
$middleware
// ...
->add(new RoutingMiddleware())
->add(function (
ServerRequestInterface $request,
ResponseInterface $response,
callable $next
) {
$params = $request->getAttribute('params');
if ($params['controller'] !== 'Api') {
$csrf = new CsrfProtectionMiddleware([
'httpOnly' => true
]);
// This will invoke the CSRF middleware's `__invoke()` handler,
// just like it would when being registered via `add()`.
return $csrf($request, $response, $next);
}
return $next($request, $response);
});
return $middleware;
}
}
public function middleware($middlewareQueue)
{
$middlewareQueue
// Catch any exceptions in the lower layers,
// and make an error page/response
->add(ErrorHandlerMiddleware::class)
// Handle plugin/theme assets like CakePHP normally does.
->add(new AssetMiddleware([
'cacheTime' => Configure::read('Asset.cacheTime')
]))
// Add routing middleware.
// Routes collection cache enabled by default, to disable route caching
// pass null as cacheConfig, example: `new RoutingMiddleware($this)`
// you might want to disable this cache in case your routing is extremely simple
->add(new RoutingMiddleware($this, '_cake_routes_'));
// Add csrf middleware.
// ->add(new CsrfProtectionMiddleware([
// 'httpOnly' => true
// ]));
return $middlewareQueue;
}
Router::scope('/', function (RouteBuilder $routes) {
// Register scoped middleware for in scopes.
$routes->registerMiddleware('csrf', new CsrfProtectionMiddleware([
'httpOnly' => true
]));
/**
* Apply a middleware to the current route scope.
* Requires middleware to be registered via `Application::routes()` with `registerMiddleware()`
*/
$routes->applyMiddleware('csrf');
//...
}
注解注册中间件和应用中间件('csrf'):
Router::scope('/', function (RouteBuilder $routes) {
// // Register scoped middleware for in scopes.
// $routes->registerMiddleware('csrf', new CsrfProtectionMiddleware([
// 'httpOnly' => true
// ]));
//
// /**
// * Apply a middleware to the current route scope.
// * Requires middleware to be registered via `Application::routes()` with `registerMiddleware()`
// */
// $routes->applyMiddleware('csrf');
//...
}
现在,编辑**/Application.php中的中间件()**函数:
/**
* Setup the middleware queue your application will use.
*
* @param \Cake\Http\MiddlewareQueue $middlewareQueue The middleware queue to setup.
* @return \Cake\Http\MiddlewareQueue The updated middleware queue.
*/
public function middleware($middlewareQueue)
{
// loading csrf Middleware ---- Add this code Block
$csrf = new CsrfProtectionMiddleware([
'httpOnly' => true
]);
$csrf->whitelistCallback(function (ServerRequest $request) {
// skip controllers
$skipedControllers = ['MyControllerToSkip', 'MyControllerToSkip2']; // EDIT THIS
if(in_array($request->getParam('controller'),$skipedControllers)) {
return true;
}
// skip debugkit
if($request->getParam('plugin') == 'DebugKit') {
return true;
}
return $request;
});
// end codeblock to add, you have to add a other code line below ->add(new RoutingMiddleware($this)) -------
$middlewareQueue
// Catch any exceptions in the lower layers,
// and make an error page/response
->add(new ErrorHandlerMiddleware(null, Configure::read('Error')))
// Handle plugin/theme assets like CakePHP normally does.
->add(new AssetMiddleware([
'cacheTime' => Configure::read('Asset.cacheTime')
]))
// Add routing middleware.
// If you have a large number of routes connected, turning on routes
// caching in production could improve performance. For that when
// creating the middleware instance specify the cache config name by
// using it's second constructor argument:
// `new RoutingMiddleware($this, '_cake_routes_')`
->add(new RoutingMiddleware($this))
->add($csrf); // <---- Don't forget to add this !
return $middlewareQueue;
}
4条答案
按热度按时间bqjvbblv1#
有两种方法。
将中间件应用于特定的路由范围(甚至路由)
根据您创建的路由,您可以将中间件仅应用于特定的作用域,例如:
这将仅将CSRF中间件应用于在
blog
和cms
作用域中连接的路由。还可以将范围进一步缩小到路由级别,并在特定路由上应用中间件:
这会将CSRF中间件仅应用于
/blog/*
路由。有条件地“手动”应用中间件
另一种方法是在合适的时候手动应用中间件。从CakePHP 3.8开始,中间件有一个名为
whitelistCallback
的白名单方法,在其中你可以检查请求对象,并返回一个布尔值来定义是否应用检查:在早期的CakePHP版本中,您必须创建一个自定义的中间件处理程序,以便访问当前的请求对象,从中提取
controller
参数,然后您必须在处理程序中 * 调用 * CSRF中间件,大致如下:请注意,在这两种情况下,您必须将中间件放在路由中间件 * 之后 *,因为这是设置控制器信息的位置。
如果适用,您还可以针对请求URL而不是路由参数进行测试,例如:
这样做的话,中间件就不会被限制在路由中间件 * 之后 *,理论上你可以把它放在你想要的任何位置。
另请参阅
*操作手册〉中间件〉跨站点请求伪造(CSRF)中间件
*操作手册〉路由〉连接作用域中间件
*操作手册〉中间件〉创建中间件
6jygbczu2#
我认为在Cake 3.6中,您应该从中间件中删除CsrfProtectionMiddleware:
队列:src/应用程序. php
bakd9h0s3#
在Cakephp 3.8中,我将所有方法实现注解到class\vendor\cakephp\cakephp\src\Http\Middleware\CsrfProtectionMiddleware.php中,因此禁用了Csrf中间件:-)
y3bcpkx14#
3.8、3.9的最新解决方案
首先从route.php中删除中间件。
注解注册中间件和应用中间件('csrf'):
现在,编辑**/Application.php中的中间件()**函数:
不要忘记最后的**-〉add($csrf);在之后-〉添加(新的路由中间件($this))**。