中间件在 Laravel 5 中如何工作?
How does middleware work in Laravel 5?
我正在尝试了解中间件在 Laravel 5 中的工作原理。我查看了中间件接口,了解到我必须实现一个 class,它有一个名为 "handle" 的方法。在 "handle" 方法中,调用了闭包。但是我不明白,应该在闭包中传递什么。什么 class 会调用我的中间件?它是如何工作的?可能就像 "foreach" 一样,所有的中间件都会被轮流调用?
更新:
我正在尝试实现自己的中间件:
interface Middleware
{
public function handle($request, Closure $next);
}
class MiddlewareCollection
{
private $middlewares;
private $request;
public function __construct(Array $middlewares, $request)
{
$this->middlewares = $middlewares;
$this->request = $request;
}
public function run()
{
$this->next(current($this->middlewares), $this->request);
}
private function next(Middleware $middleware, $request)
{
$middleware->handle($request, function($request) {
//How can I call the next middleware?
});
}
}
class FirstMiddleware implements Middleware
{
public function handle($request, Closure $next) {
echo $request.'first ';
return $next($request);
}
}
class SecondMiddleware implements Middleware
{
public function handle($request, Closure $next) {
echo $request.'second ';
return $next($request);
}
}
class ThirdMiddleware implements Middleware
{
public function handle($request, Closure $next) {
echo $request.'third ';
return $next($request);
}
}
$middlewares = [
'first' => new FirstMiddleware(),
'second' => new SecondMiddleware(),
'third' => new ThirdMiddleware()
];
$middlewareCollection = new MiddlewareCollection($middlewares, 'Request');
$middlewareCollection->run();
这样做对不对?我也无法理解我应该如何在 MiddlewareCollection class.
的 next() 方法中调用下一个中间件
这个 blog post 对于解释中间件的工作原理以及如何从头开始构建中间件非常有用。
不过,我将使用 Laravel 附带的示例,auth 中间件 (app/Http/Middleware/Authenticate.php
)。此中间件保护路由并确保尝试访问它们的用户已登录。
public function handle($request, Closure $next)
{
if ($this->auth->guest()) {
if ($request->ajax()) {
return response('Unauthorized.', 401);
} else {
return redirect()->guest('auth/login');
}
}
return $next($request);
}
handle
函数为我们完成所有工作,在这种情况下,它首先接受 $request
,这是我们想要去的地方或我们发送的请求到服务器。
接下来我们将检查用户是否已登录或者是 if ($this->auth->guest())
的访客
如果我们登录,那么这将 return false 并且我们将继续 return $next($request);
这将允许我们照常进行。
如果我们没有登录并且是访客,我们将此语句作为 true 传递并继续 if
语句。
然后我们会点击:
if ($request->ajax()) {
return response('Unauthorized.', 401);
}
这可能是不言自明的,但它会检查请求是否是 ajax 调用,如果是,那么它将 return 401 未经授权的响应。
如果它不是 ajax 请求,那么我们点击:
else {
return redirect()->guest('auth/login');
}
这会将访客重定向到登录页面。一旦他们登录,请求就可以继续,他们的请求将照常进行。
因此,我可以使用此中间件保护路由 www.mywebsite.com/admin
,如果我没有登录,那么我将被重定向到 www.mywebsite.com/auth/login
,一旦我登录,我将 return 到我原来的要求 www.mywebsite.com/admin
没有任何问题。
正如我首先提到的,请查看该博客 post,因为它确实有一些有用的解释和更简单的示例。
中间件,在Laravel之前的5个被称为filter。中间件拦截请求然后在你的中间件里面处理 class 负责接下来的工作就做什么。根据您的处理方式,有两种类型的中间件。
在控制传递给控制器之前检查前中间件。逻辑在您的 handle 方法中。比如,您想在留言簿上登录到 post。所以,如果你在应用中间件之前使用,你的逻辑就像
- 检查用户是否未登录
- 将他们重定向回登录页面
- 否则,让请求按原样进行
代码将是这样的,
public function handle($request, Closure $next)
{
// Perform action
return $next($request);
}
after 中间件在控制器完成其所有工作后进行检查,并将响应传递给用户。为此,您可以将其视为已发出 API 请求,并且您希望在每个请求完成时刷新令牌。为此,代码将是
public function handle($request, Closure $next)
{
$response = $next($request);
// Perform action
return $response;
}
在这里,为了简单起见,您可以考虑 $next 方法,因为它会将控制权传递给控制器。对于之前的中间件,它会检查逻辑,然后将 return 控件传递给控制器,最后 return 响应。
另一方面,after 中间件将控制传递给控制器,当控制器完成其工作时,某些内容将存储在 $response 变量中并执行一些逻辑。之后是 returning $response。
希望现在清楚了。
我正在尝试了解中间件在 Laravel 5 中的工作原理。我查看了中间件接口,了解到我必须实现一个 class,它有一个名为 "handle" 的方法。在 "handle" 方法中,调用了闭包。但是我不明白,应该在闭包中传递什么。什么 class 会调用我的中间件?它是如何工作的?可能就像 "foreach" 一样,所有的中间件都会被轮流调用? 更新: 我正在尝试实现自己的中间件:
interface Middleware
{
public function handle($request, Closure $next);
}
class MiddlewareCollection
{
private $middlewares;
private $request;
public function __construct(Array $middlewares, $request)
{
$this->middlewares = $middlewares;
$this->request = $request;
}
public function run()
{
$this->next(current($this->middlewares), $this->request);
}
private function next(Middleware $middleware, $request)
{
$middleware->handle($request, function($request) {
//How can I call the next middleware?
});
}
}
class FirstMiddleware implements Middleware
{
public function handle($request, Closure $next) {
echo $request.'first ';
return $next($request);
}
}
class SecondMiddleware implements Middleware
{
public function handle($request, Closure $next) {
echo $request.'second ';
return $next($request);
}
}
class ThirdMiddleware implements Middleware
{
public function handle($request, Closure $next) {
echo $request.'third ';
return $next($request);
}
}
$middlewares = [
'first' => new FirstMiddleware(),
'second' => new SecondMiddleware(),
'third' => new ThirdMiddleware()
];
$middlewareCollection = new MiddlewareCollection($middlewares, 'Request');
$middlewareCollection->run();
这样做对不对?我也无法理解我应该如何在 MiddlewareCollection class.
的 next() 方法中调用下一个中间件这个 blog post 对于解释中间件的工作原理以及如何从头开始构建中间件非常有用。
不过,我将使用 Laravel 附带的示例,auth 中间件 (app/Http/Middleware/Authenticate.php
)。此中间件保护路由并确保尝试访问它们的用户已登录。
public function handle($request, Closure $next)
{
if ($this->auth->guest()) {
if ($request->ajax()) {
return response('Unauthorized.', 401);
} else {
return redirect()->guest('auth/login');
}
}
return $next($request);
}
handle
函数为我们完成所有工作,在这种情况下,它首先接受 $request
,这是我们想要去的地方或我们发送的请求到服务器。
接下来我们将检查用户是否已登录或者是 if ($this->auth->guest())
的访客
如果我们登录,那么这将 return false 并且我们将继续 return $next($request);
这将允许我们照常进行。
如果我们没有登录并且是访客,我们将此语句作为 true 传递并继续 if
语句。
然后我们会点击:
if ($request->ajax()) {
return response('Unauthorized.', 401);
}
这可能是不言自明的,但它会检查请求是否是 ajax 调用,如果是,那么它将 return 401 未经授权的响应。
如果它不是 ajax 请求,那么我们点击:
else {
return redirect()->guest('auth/login');
}
这会将访客重定向到登录页面。一旦他们登录,请求就可以继续,他们的请求将照常进行。
因此,我可以使用此中间件保护路由 www.mywebsite.com/admin
,如果我没有登录,那么我将被重定向到 www.mywebsite.com/auth/login
,一旦我登录,我将 return 到我原来的要求 www.mywebsite.com/admin
没有任何问题。
正如我首先提到的,请查看该博客 post,因为它确实有一些有用的解释和更简单的示例。
中间件,在Laravel之前的5个被称为filter。中间件拦截请求然后在你的中间件里面处理 class 负责接下来的工作就做什么。根据您的处理方式,有两种类型的中间件。
在控制传递给控制器之前检查前中间件。逻辑在您的 handle 方法中。比如,您想在留言簿上登录到 post。所以,如果你在应用中间件之前使用,你的逻辑就像
- 检查用户是否未登录
- 将他们重定向回登录页面
- 否则,让请求按原样进行
public function handle($request, Closure $next)
{
// Perform action
return $next($request);
}
after 中间件在控制器完成其所有工作后进行检查,并将响应传递给用户。为此,您可以将其视为已发出 API 请求,并且您希望在每个请求完成时刷新令牌。为此,代码将是
public function handle($request, Closure $next)
{
$response = $next($request);
// Perform action
return $response;
}
在这里,为了简单起见,您可以考虑 $next 方法,因为它会将控制权传递给控制器。对于之前的中间件,它会检查逻辑,然后将 return 控件传递给控制器,最后 return 响应。
另一方面,after 中间件将控制传递给控制器,当控制器完成其工作时,某些内容将存储在 $response 变量中并执行一些逻辑。之后是 returning $response。
希望现在清楚了。