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とパスワードの変更画面を追加すれば、これで完成!