LaravelLaravel开发实践

Laravel从入门到上线运营-08中间件篇

2019-10-11  本文已影响0人  3275508ab630

Laravel从入门到上线运营-08中间件篇

上次我们简单的做了一下登录注册,我们使用了框架里写好的登录方法 auth()->login($user)

简单的解释一下登录原理,执行这个登录方法会在你的浏览器里保存一个 cookie。当你访问这个网站的时候,会自动读取 cookie,如果有用户信息的 cookie 存在,就会拿这个数据去数据库里查询

cookie 没有过期或者其他问题的话,就是每次访问网页,就会都去查询一次用户表,用户存在即代表该用户为登录状态。所以同一个设备下使用不同浏览器,或者使用 chrome 的无痕模式,是不同登录状态。

我们做一个验证,访问 b/login,登录一个账号,再在 Providers/AppServiceProvider.php 文件里添加数据库查询记录监听

<?php

namespace App\Providers;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Str;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        //sql日志记录
        DB::listen(function ($q) {
            info(Str::replaceArray('?', $q->bindings, $q->sql). ' '. $q->time. 'ms'); //info 日志是记录
        });
    }
}

请求一次网页,在 storage/logs 的今天日志文件里就会多一段记录。

[2019-10-11 13:01:29] local.INFO: select * from `users` where `id` = 1 limit 1 73.17ms

讲完登录我们再讲一下 csrf,我们昨天讲到除了 get 以外的请求,都需要通过 csrf 验证。那每次请求就是通过 csrf 的中间件的方式去验证的。中间件文件放在 app/Http/Middleware 目录下。

其中的 VerifyCsrfToken.php 就是 csrf 中间件。那一个请求具体经过哪些中间件是在 blog/app/Http/Kernel.php 中配置。

protected $middleware = [
        \App\Http\Middleware\TrustProxies::class,
        \App\Http\Middleware\CheckForMaintenanceMode::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    ];

第一个数组就是所有请求都会经过的中间件。我们直接把最后一个注释掉,它的作用是把请求参数中的空字符串转为 null,没什么用。

protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            // \Illuminate\Session\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

        'api' => [
            'throttle:60,1',
            'bindings',
        ],
    ];

第二个数组是根据不同的请求方式经过不同的中间件,就两种 web 网页请求,api 接口请求。

protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
    ];

第三个数组是对中间件命名,名字会在路由中用到。

protected $middlewarePriority = [
    \Illuminate\Session\Middleware\StartSession::class,
    \Illuminate\View\Middleware\ShareErrorsFromSession::class,
    \App\Http\Middleware\Authenticate::class,
    \Illuminate\Session\Middleware\AuthenticateSession::class,
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
    \Illuminate\Auth\Middleware\Authorize::class,
];

第四个数组是规定中间件的执行顺序。

现在我们自己来建一个中间件,用来记录每次的请求。使用命令行创建

php artisan make:middleware RequestInfo
<?php

namespace App\Http\Middleware;

use Closure;

class RequestInfo
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request $request
     * @param  \Closure $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        //请求记录
        info("\r\r=============================================================\r
[url]: " . $request->ip() . "\r" . $request->url() . "         " . $request->getMethod() . "\r\r
[Authorization]:\r" . $request->header('Authorization') . "\r\r
[body]:\r" . json_encode($request->all(), true) . "\r");

        return $next($request);
    }
}

app/Http/Kernel.php 第一个数组中加入它

    protected $middleware = [
        \App\Http\Middleware\TrustProxies::class,
        \App\Http\Middleware\CheckForMaintenanceMode::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \App\Http\Middleware\RequestInfo::class,
//        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    ];

这时候我们访问网页就会有详细的信息记录下来,开发的时候可以看看自己到底传了什么参数过来。

我们再来试试在路由上添加中间件,假设我们网站的首页是需要登录,框架已经帮我们写好了一个登录验证中间件,修改路由文件。

Route::get('/', 'IndexController@index')->middleware('auth'); // 给该路由添加 auth 中间件
Route::get('register', 'RegisterController@index');
Route::post('register', 'RegisterController@register');

Route::get('login', 'LoginController@index')->name('login'); //name 方法是对路由进行命名,个人觉得路由地址本身就是名字了,再起名字似乎多余了
Route::post('login', 'LoginController@login');

打开 chrome 里的无痕模式,访问 b/。就会发现被自动转到了登录界面,这就是 'auth' => \App\Http\Middleware\Authenticate::class, 该中间件启的作用。

还可以在 controller 中的 __construct 对方法进行中间件设置。

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

中间件的其他部分,同学们自行学习。

上一篇 下一篇

猜你喜欢

热点阅读