概要
Laravelではapp/storageへstoreAsメソッドなどでファイルを保存することができます。保存したファイルへのアクセスは、ファイルが保存されているディレクトリへのシンボリックリンクを貼り、パスを入力することで容易にできます。
例:app/storage/thumbnailにkuma.jpegを保存
'links' => [
public_path('storage') => storage_path('app/public'),
public_path('thumbnail') => storage_path('app/thumbnail'), //追加
],
http://localhost:8000/thumbnail/kuma.jpeg
しかし会員制サイトの場合、外部のユーザーがURLを入力するだけでファイルへアクセスできることは望ましくありません。
今回は非認証ユーザーからのアクセスはログイン画面へリダイレクトし、認証済みユーザーのみがアクセスできるようにする方法を備忘録としてまとめます。
結論
Route::middleware('auth:user')->group(function () {
// (略)
Route::get('{file}/{any}', [AuthFileController::class, 'getFile'])
->where(['file' => 'pdf_file|thumbnail', 'any' => '.*'])
->name('auth.file');
// (略)
});
class AuthFileController extends Controller
{
public function getAssetFile($file, $any)
{
// ファイルの存在を判定
if(Storage::disk("local")->exists($file."/".$any)) {
// storage/app下のファイルを返す
return response()->file(Storage::path($file."/".$any));
} else {
// 404エラーの送信
abort(404);
}
}
}
詳細
route.php
middlewareのgroupメソッド内に追加することで、ファイルへのアクセスパスに認証を通すことができます。
Route::middleware('auth:user')->group(function () {
whereメソッド
Route::get('{file}/{any}', [AuthFileController::class, 'getFile'])
->where(['file' => 'pdf_file|thumbnail', 'any' => '.*'])
->name('auth.file');
whereメソッドによって、{file}に入るルートパラメータの制約条件を追加することができます。この指定により、任意のファイルへのアクセスに認証を通す事ができます。今回の例ではstorage/thumbnailへのファイルと、storage/pdf_fileへのアクセスに認証を追加しています。
正規表現の制約
他のファイルへの認証を追加する場合、whereメソッドのルートパラメータへの追加と、シンボリックの追加のみで対応できます。
AuthFileController.php
こちらは今回の本筋とは少しずれますが、ルートパラメータからファイルの存在を確認し、なければ404エラーを返すようにしています。こちらは状況に応じてカスタマイズが必要な箇所だと思います。
まとめ
ファイルへのアクセス認証をまとめました。会員制サイトの制作に携わることがこれからも多そうなので、もし次同様のケースがあれば適用できればと思います。