laravel5.5で、特定のディレクトリにBasic認証(管理画面から変更可)をmiddlewareで実装してみた。
1, laravelで制限&認証と言えば、middlewareを使うのが一般的
| 1 | php artisan make:middleware BasicAuthMiddleware | 
2, 次にlaravelに登録(app/Http/Kernel.php)します。
// 通常のユーザ認証と同じように、指定したルーティングに対してだけBasic認証を行う
protected $middleware = [];の方に登録すると、全てのルーティングに対して行う
| 1 2 3 | protected $routeMiddleware = [     'basicauth' => 'App\Http\Middleware\BasicAuthMiddleware', ]; | 
3, BasicAuthMiddlewareの実装(basic認証)を書く
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |     public function handle($request, Closure $next)     {         // PHPによるBasic認証 http://qiita.com/mpyw/items/dc2cb3632370389d700e         switch (true) {             case !isset($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']):             case $_SERVER['PHP_AUTH_USER'] !== 'test':             case $_SERVER['PHP_AUTH_PW']   !== 'test':                 header('WWW-Authenticate: Basic realm="Enter username and password."');                 header('Content-Type: text/plain; charset=utf-8');                 die('このページを見るにはログインが必要です');         }         header('Content-Type: text/html; charset=utf-8');         return $next($request);     } | 
4, web.phpにbasic認証のかけたいURLを指定する
| 1 2 3 4 5 6 7 8 | Route::group(['middleware' => 'basicauth'], function() {     // ログイン画面は認証していなくても、表示される。     Route::get('login',     'Auth\LoginController@showLoginForm')->name('user.login');     Route::post('login',    'Auth\LoginController@login')->name('user.login');     Route::get('register',  'Auth\LoginController@showRegisterForm')->name('register');     Route::post('register', 'Auth\RegisterController@register'); }); | 
5, このままだとBasic認証のID/PASSが固定値なのでMySQLのテーブルから持ってくるように変更する。
※アクセスされたサブディレクトリ毎に、Basic認証のID/PASSが違う仕様
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |     public function handle($request, Closure $next)     {        // https://domain.com/section/abcdef0123456789/なんたら、という形式になっているのでハッシュ値を取得         if (preg_match('/section\/[a-f0-9]+/',  $request->path(), $matches)) {             $section_unique_id = str_replace('section/', '', $matches[0]);         }else{             $section_unique_id = '';         }         //最初に適合したIDレコードを取得         $section = Section::where('section_unique_id', $section_unique_id)->first();         // storage\logs\laravel.logに、パスを出力         // \Log::info('Requested PATH ' . $request->path());         // \Log::info('' . $section);         // PHPによるBasic認証 http://qiita.com/mpyw/items/dc2cb3632370389d700e         // Basic認証ダイアログから入力されたID/PASS(最初は未入力なので空文字を代入)         $id = isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : '';         $password = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : '';         // ハッシュ化済みパスワードのソルトを使って、受け取ったパスワードをハッシュ化後に比較         // 認証できなければ、何度でもBasic認証ダイアログを表示!         if($section['basic_auth_id'] === $id && \Hash::check($password, $section['basic_auth_pass'])) {         }else{             header('WWW-Authenticate: Basic realm="Enter username and password."');             header('Content-Type: text/plain; charset=utf-8');             die('このページを見るにはログインが必要です');         }         // 有効なアカウントなら、先に進める         header('Content-Type: text/html; charset=utf-8');         return $next($request);     } | 
Basic認証のIDとパスワードの変更画面を追加すれば、これで完成!