首页 » Web技术 » Laravel » 正文

[Laravel 5 教程学习笔记] 十六、中间件

假设我们已经完成了网站并部署到实际环境中,每个人都可以访问列表页和文章内容页,而只有注册并且登录的用户才可以访问添加文章页,也就是说访客是没有权限发布文章的。下面就介绍如何通过中间件来实现该功能。

访问 http://laravel.dev/auth/logout ,退出登录,这时访问 http://laravel.dev/articles/create,可以看到访客依然能够发布文章,这是我们不允许的,所以,修改 Article 控制器的 create()  方法:

    public function create(){
        if(Auth::guest()){
            return redirect('articles');
        }
        return view('articles.create');
    }

这时刷新页面,页面会自动跳转到文章列表页。

但是我们可以设想一下,如果所有需要验证权限的地方都这么一遍遍的写,会非常的麻烦。幸运的是,这里有一个更好的内置方法–中间件(Middleware)。中间件文件位于 app/Http/Middleware/ 目录下。可以通过 app/Http/Kernel.php 注册中间件,每一个请求都要执行的添加到 $middleware 中,而只在特殊位置需要的添加到 $routeMiddleware 中。

例如我们在线上环境中要进行维护或者一些组件的升级,需要进入维护模式,可以在命令行执行:

D:\wamp\www\laravel5>php artisan down
Application is now in maintenance mode.

这时无论访问哪个页面,都会看到下面的提示:

laravel-down

这其实就是使用的 'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode' 中间件。

使用下面的命令取消维护模式:

D:\wamp\www\laravel5>php artisan up
Application is now live.

Article 控制器中添加构造方法:

    public function __construct(){
        $this->middleware('auth');
    }

再次访问 http://laravel.dev/articles/create,或者列表页、或者文章详情页,可以看到都会自动跳转到登录页面。但是有时候我们并不想对每个路由或者控制器中的每一个方法都应用中间件,而是对其中的某一个或者某几个方法应用,我们就可以这么做:

    public function __construct(){
        //除了主页之外
        $this->middleware('auth', ['except' => ['index','show']]);
        //只有发布页
        //$this->middleware('auth', ['only' => 'create']);
    }

这时除了访问发布页,其他页面都不需要进行登录验证。

我们也可以在路由中使用中间件:

Route::get('about', ['middleware' => 'auth', function(){
    return '该页面只有用户登录之后才会显示';
}]);

创建自己的中间件

首先在命令行执行:

D:\wamp\www\laravel5>php artisan make:middleware Demo
Middleware created successfully.

现在生成了一个 app/Http/Middleware/Demo.php 文件,修改其中的 handle() 方法:

	public function handle($request, Closure $next)
	{
        if($request->is('articles/create') && $request->has('foo')){
            return redirect('articles');
        }
		return $next($request);
	}

之后到 app/Http/Kernel.php 中修改:

    protected $middleware = [
        'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
        'Illuminate\Cookie\Middleware\EncryptCookies', 
        'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse', 
        'Illuminate\Session\Middleware\StartSession', 
        'Illuminate\View\Middleware\ShareErrorsFromSession', 
        'App\Http\Middleware\VerifyCsrfToken', 
        //添加该行
        'App\Http\Middleware\Demo'
    ];

直接访问 http://laravel.dev/articles/create ,页面不跳转,而如果访问 http://laravel.dev/articles/create?foo=bar ,可以看到页面会自动跳转到 http://laravel.dev/articles 。说明我们添加的中间件起作用了。


该篇属于专题:《Laravel 5 基础视频教程学习笔记

本文共 7 个回复

  • dodo 2015/11/12 11:57

    Article 控制器的 create() 方法中的if(Auth::guest()){ 少了 \应该是if(\Auth::guest()){ :wink:

    • oyxhm 2015/12/01 23:06

      @ dodo 是的,我也发现这个问题,求解是为什么?

  • zjien 2016/03/23 11:23

    这是因为Auth处于根命名空间的原因吗

  • crazy_coder 2016/10/10 20:02

    public function handle($request, Closure $next) { if($request->is('articles/create') && $request->has('foo')){ return redirect('articles'); } return $next($request); } 这里的$request->has('foo')的具体含义是?

  • crazy_coder 2016/10/10 20:11

    没看下文,看完下面感觉自己是个傻逼

发表评论