Laravel 앱의 특정 파일에 대한 액세스 제한

6523 단어 securitylaravelphp
우리는 일반적으로 앱 파일이 공개되기를 원합니다(프로필 사진, 제품 이미지 등). 하지만 로그인한 사용자 또는 특정 역할을 가진 사용자에게만 액세스를 제한하려면 어떻게 해야 할까요? 오늘 당신은 방법을 알게 될 것입니다.

우리가 해야 할 일



구현하기 전에 전략을 이해해야 합니다. 기본적으로 다음과 같이 하겠습니다.
  • 새 디스크를 정의합니다. 이는 파일을 쉽게 읽고 쓰기 위한 것입니다
  • .
  • 파일 반환을 담당할 컨트롤러 및 방법을 정의합니다
  • .
  • 이 새 디스크의 요소에 대한 경로를 생성합니다
  • .
  • 경로 확보 중

  • 간단하죠? 글쎄요.

    1. 새 디스크 정의



    이를 위해 이를 처리하는 구성 파일로 이동합니다: config/filesystems.php . 앱에서 제공하는 다양한 디스크를 정의합니다.

    "디스크"는 드라이버와 위치를 나타내는 것에 지나지 않습니다. 앱의 로컬 디스크, AWS S3 또는 다른 공급자를 가리키는 디스크가 있을 수 있습니다.

    이 경우에는 'files' 디스크를 생성합니다. 이것은 /storage/app/files 디렉토리를 가리키는 로컬 디스크가 됩니다. 해당 디렉토리에는 제한된 파일을 저장할 위치가 있습니다.

    'disks' => [
        // ...
        'files' => [
            'driver' => 'local',
            'root' => storage_path('app/files'),
            'visibility' => 'private',
        ],
    ],
    


    Notice that we set the visibility as 'private'.



    2. 컨트롤러 정의



    컨트롤러를 만듭니다.

    php artisan make: controller FilesController --invokable
    


    I opted for a single action controller since it will only have one method.



    새로 생성된 컨트롤러로 이동하여 로직을 구현합니다.

    <?php
    
    namespace App\Http\Controllers;
    
    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Storage;
    use Symfony\Component\HttpFoundation\StreamedResponse;
    
    class FilesController extends Controller
    {
        public function __invoke(Request $request, $path)
        {
            abort_if(
                ! Storage::disk('files') ->exists($path),
                404,
                "The file doesn't exist. Check the path."
            );
    
            return Storage::disk('files')->response($path);
        }
    }
    


    코드를 확인하면 2가지 작업을 수행하는 것을 볼 수 있습니다. 먼저 파일이 존재하는지 확인합니다. 그렇지 않으면 404 응답을 반환하여 호출을 중단합니다. 그런 다음 파일 반환 요청에서 전송된 경로만 사용합니다.

    우리 메서드는 $path 매개변수를 수신할 것으로 예상합니다.

    3. 경로 정의


    routes/web.php로 이동하여 새 경로를 추가합니다. 내 경우에는 다음 형식을 제공합니다.

    <?php
    
    use App\Http\Controllers\FilesController;
    use Illuminate\Support\Facades\Route;
    
    // Other routes..
    
    Route::get('/files/{path}', FilesController::class); // <--
    


    이제 컨트롤러에 도달하는 $path 변수의 출처를 이해했습니다. 따라서 이 경로는 다음과 같은 요청을 캡처합니다. https://laravel8.test/files/my-file.jpg

    4. 경로 확보



    이제 경로만 확보하면 됩니다. 이를 달성하기 위해 다양한 옵션이 있으며 이는 앱에서 처리하려는 방법에 따라 달라집니다. 이 예에서는 'auth' 미들웨어를 사용하여 이를 수행합니다. ACL 시스템을 사용하여 경로 또는 다른 대안에 대한 액세스를 제한할 수도 있습니다.

    Route::get('/files/{path}', FilesController::class)->middleware('auth');
                                                       ^^^^^^^^^^^^^^^^^^^^
    


    테스트로 보안 디렉토리/storage/app/arsenal-goal.jpg에 이미지를 업로드했습니다. 또한 Laravel Breeze를 설치하고 사용자를 생성하여 인증된 사용자의 유무에 관계없이 요청을 비교했습니다.

    결과:



    왼쪽에는 로그인한 사용자로 접속을 시도하는 경우가 있습니다. 오른쪽에서 로그인하지 않고 시크릿 모드에서 액세스를 시도했기 때문에 로그인으로 리디렉션되는 것을 볼 수 있습니다.

    좋은 웹페이지 즐겨찾기