laravel認証を使った画像/js/cssファイルの非公開設定について
laravel5.1では、通常publicフォルダ以下に画像/js/cssファイルを配置して、認証なしでアクセスできるようにしている(特定のユーザしか見れないような画像は通常storageフォルダに置く)
通常であれば、publicフォルダに.htaccessでBASIC認証をかければ非公開なんだけど、仕様的にかけられない場合などに活用して下さい。
今回行ったのは、画像/js/cssファイルを、publicフォルダからstorageフォルダに移行して、routes.php経由(laravel認証後、ファイル出力処理を行う)でアクセスできるようにしてみた。
1, 画像/js/cssファイルを、publicフォルダからstorageフォルダに移行
これで、laravelでファイル出力を行わない限り、アクセスできなくなる
※公開しているログイン画面で使われる「画像/js/cssファイル」はpublicフォルダに配置しておく(認証前でもアクセスできるようにする)
2, 通常通り、bladeファイルで画像/js/cssファイルを指定されたら、routes.phpで拾えるように記述を追記する
1 2 3 4 5 6 7 |
Route::group(['middleware' => 'auth'], function () { // 画像・JS・CSSファイルは、ログインしないと見れない。ログイン画面のロゴ画像はpublicに入れる // パラメータ引数を何でもありにして、スラッシュで複数パラメータにならないようにしている Route::get('/images/{path?}', 'DownloadsController@download')->where(['path' => '.*']); Route::get('/js/{path?}', 'DownloadsController@download')->where(['path' => '.*']); Route::get('/css/{path?}', 'DownloadsController@download')->where(['path' => '.*']); |
3, ファイル出力処理のコントローラーを作る(php artisan make:controller DownloadsController)
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 37 38 39 40 41 |
<?php namespace App\Http\Controllers; //use Illuminate\Http\Request; use Request; // REQUEST_URI取得のため use Response; // HTTPレスポンス use FInfo; // MIME取得のため use File; // ファイル内容取得 use App\Http\Requests; use App\Http\Controllers\Controller; class DownloadsController extends Controller { public function download() { // ファイルパスは引数ではもらわず、ドメイン名以下のリクエストURLで取得 $pathToFile = storage_path(preg_replace('/^\/shop\/(admin\/)?/', '', ltrim(Request::server('REQUEST_URI')))); $info = new FInfo(FILEINFO_MIME_TYPE); $mine_type = $info->file($pathToFile); // pathinfoのjsとcssはバグっているらしいので、拡張子判定で上書きする https://bugs.php.net/bug.php?id=53035 switch(pathinfo($pathToFile, PATHINFO_EXTENSION)){ case 'css': $mine_type = 'text/css'; break; case 'js': $mine_type = 'application/javascript'; break; default: } // 画像/js/cssファイルの中身を読み込んでブラウザ出力 $contents = File::get($pathToFile); $response = Response::make($contents, 200); $response->header('Content-Type', $mine_type); return $response; } } |
4, これで、一般ユーザ認証は問題なく画像/js/cssファイルへアクセス出来るようになったが、admin認証など別の認証をしている場合にアクセス出来なくなってします(一般ユーザ認証で守らているため)
一般ユーザ https://localhost/shop ←OK
管理者ユーザ https://localhost/shop/admin ←NG(一般ユーザ認証になってしまう)
4-a, 解決策としては、adminフォルダ以下のbladeファイルのパス指定にプレフィックスとしてadmin/を追加
{!! Html::script(‘admin/js/admin.js’); !!}
{!! Html::style(‘admin/css/admin.css’); !!}
4-b, admin認証の時でも同じ処理をするようにroutes.phpに追記。
1 2 3 4 5 6 7 8 |
// admin以下は、管理者認証していないとアクセスできない! Route::group(['prefix'=>'admin','middleware'=>'admin'],function(){ // 画像・JS・CSSファイルは、ログインしないと見れない。ログイン画面のロゴ画像はpublicに入れる // パラメータ引数を何でもありにして、スラッシュで複数パラメータにならないようにしている Route::get('/images/{path?}', 'DownloadsController@download')->where(['path' => '.*']); Route::get('/js/{path?}', 'DownloadsController@download')->where(['path' => '.*']); Route::get('/css/{path?}', 'DownloadsController@download')->where(['path' => '.*']); |
5, 画像ファイルのアップロード機能があった場合は、public_pathからstorage_pathへ変更しておく事!
これでlaravelでも、ユーザ認証されていないと画像/js/cssファイルにアクセス出来なくなるはず(bladeファイルの書き方は、通常通りでOK!)