Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何处理laravel 5中的私有图像?_Laravel_Laravel 5 - Fatal编程技术网

如何处理laravel 5中的私有图像?

如何处理laravel 5中的私有图像?,laravel,laravel-5,Laravel,Laravel 5,我对Laravel是新手,我尝试存储私有图像,以便只有经过身份验证的用户才能访问它们。首先,我将图像存储在Public/UserImages文件夹中。但在这里,所有的图片都可以通过检查chrome元素,然后更改用户ID,让未经身份验证的用户访问。请帮帮我 这真的取决于你。它需要在公共目录之外-我个人会选择资源/上传或存储/上传,或者使用 无论您选择什么,您都需要一条路径,在首先检查用户是否具有访问权限后,获取文件并将其传递给用户。以下是我如何解决在Laravel 5中存储图像的问题,以便只有经过

我对Laravel是新手,我尝试存储私有图像,以便只有经过身份验证的用户才能访问它们。首先,我将图像存储在Public/UserImages文件夹中。但在这里,所有的图片都可以通过检查chrome元素,然后更改用户ID,让未经身份验证的用户访问。请帮帮我

这真的取决于你。它需要在
公共
目录之外-我个人会选择
资源/上传
存储/上传
,或者使用


无论您选择什么,您都需要一条路径,在首先检查用户是否具有访问权限后,获取文件并将其传递给用户。

以下是我如何解决在Laravel 5中存储图像的问题,以便只有经过身份验证的用户才能查看图像。未经身份验证的用户将被定向到登录页面。我的服务器是Ubuntu/Apache2服务器

  • 创建目录/var/www/YOURWEBSITE/app/Assets/Images

  • 将路由添加到app/Http/routes.php

    Route::get('/images/{file}','ImageController@getImage');

  • 创建控制器app/Http/Controllers/ImageController.php

    <?php
    namespace App\Http\Controllers;
    
    use App\Http\Requests;
    
    use App\Http\Controllers\Controller;
    
    use Illuminate\Http\Request;
    
    use Auth;
    
    class ImageController extends Controller {
    
        public function __construct()
       {
            $this->middleware('auth');
       } 
        public function getImage($filename) {
           $path = '/var/www/YOURWEBSITE/app/Assets/Images/'.$filename;
           $type = "image/jpeg";
           header('Content-Type:'.$type);
           header('Content-Length: ' . filesize($path));
           readfile($path);
    
        }
    
     }
    
  • 当然,这里假设test.jpg是/var/www/YOURWEBSITE/app/Assets/Images中的一个文件/


    当然,您可以添加更多逻辑,例如不硬编码图像路径等。这只是一个实施身份验证的简单示例。请注意,在控制器构造函数中使用了中间件(“auth”)。

    几天前,我遇到了同样的问题,并提出了以下解决方案:

  • 首先要做的是将文件上载到非公共目录。我的应用程序正在存储扫描的发票,因此我将把它们放在
    存储/app/invoices
    中。上载文件和生成url的代码为:

    // This goes inside your controller method handling the POST request.
    
    $path = $request->file('invoice')->store('invoices');
    $url = env('APP_URL') . Illuminate\Support\Facades\Storage::url($path);
    
    <?php
    
    namespace App\Http\Controllers;
    
    use Illuminate\Support\Facades\Storage;
    
    class FileController extends Controller
    {
    
        public function __construct()
        {
            $this->middleware('auth');
        }
    
        public function __invoke($file_path)
        {
            if (!Storage::disk('local')->exists($file_path)) {
                abort(404);
            }
    
            $local_path = config('filesystems.disks.local.root') . DIRECTORY_SEPARATOR . $file_path;
    
            return response()->file($local_path);
        }
    }
    
    返回的url应产生如下结果

  • 现在,您必须创建一个使用
    auth中间件
    的控制器,以确保用户经过身份验证。然后,定义一个从私有目录获取文件并将其作为文件响应返回的方法。这将是:

    // This goes inside your controller method handling the POST request.
    
    $path = $request->file('invoice')->store('invoices');
    $url = env('APP_URL') . Illuminate\Support\Facades\Storage::url($path);
    
    <?php
    
    namespace App\Http\Controllers;
    
    use Illuminate\Support\Facades\Storage;
    
    class FileController extends Controller
    {
    
        public function __construct()
        {
            $this->middleware('auth');
        }
    
        public function __invoke($file_path)
        {
            if (!Storage::disk('local')->exists($file_path)) {
                abort(404);
            }
    
            $local_path = config('filesystems.disks.local.root') . DIRECTORY_SEPARATOR . $file_path;
    
            return response()->file($local_path);
        }
    }
    
  • 这是一个非常可重用的代码片段,适用于处理私有文件的所有项目:)

    这里介绍如何在Laravel 5.7中实现它 要拥有私有文件(图像),您需要通过路由=>controller流提供文件。您的身份验证中间件将处理身份验证和权限。如果需要进一步授权,请在控制器中处理

    所以首先我们设定一条路线: 在这里,我们可以使用一条路径来处理所有文件[我个人不喜欢这样]。 我们可以使用这样的路由(就像一个通配符)

    你也可以这样命名:

    Route::get('/storage/{fileName}', 'FileController@fileStorageServe')
    ->where(['fileName' => '.*'])->name('storage.gallery.file');
    
    否则我们为每种类型/类别的文件创建一个路由:(优点:您将能够更好地控制可访问性。(每种路由和资源类型及其规则。如果您想通过通配符路由(我称之为)实现这一点,您需要有条件块(否则,处理所有不同的情况。这是不必要的操作[当路由分开时,直接转到右侧区块更好,此外,它允许您更好地组织权限处理])

    我们现在设置了路线控制器 通配符之一

      <?php
         public function fileStorageServe($file) {
                    // know you can have a mapping so you dont keep the sme names as in local (you can not precsise the same structor as the storage, you can do anything)
    
                    // any permission handling or anything else
    
                    // we check for the existing of the file 
                    if (!Storage::disk('local')->exists($filePath)){ // note that disk()->exists() expect a relative path, from your disk root path. so in our example we pass directly the path (/.../laravelProject/storage/app) is the default one (referenced with the helper storage_path('app')
                        abort('404'); // we redirect to 404 page if it doesn't exist
                    } 
                //file exist let serve it 
    
    // if there is parameters [you can change the files, depending on them. ex serving different content to different regions, or to mobile and desktop ...etc] // repetitive things can be handled through helpers [make helpers]
    
                    return response()->file(storage_path('app'.DIRECTORY_SEPARATOR.($filePath))); // the response()->file() will add the necessary headers in our place (no headers are needed to be provided for images (it's done automatically) expected hearder is of form => ['Content-Type' => 'image/png'];
    
    // big note here don't use Storage::url() // it's not working correctly.  
                }
    
    <img src="{{route('routeName', ['fileParam' => $storageRelativePath])}}" />
    
    相同,但我们只提供文件名

    注意事项: 发送此类响应的最佳方法是使用response()->file();。 这就是你将在5.7文档中找到的。 这是针对Image::make($storagePath)->response();的性能,除非您需要动态修改它


    您可以在medium中查看我的文章:

    会更好,如果base_path()允许代码从一个地方移动到另一个地方用于生成绝对路径的开头,而不是全部输入。有人知道如何使这些文件显示在pdf上吗?感谢这是我找到的最佳解决方案。感谢“*”不安全,允许使用../并可以访问根文件作为.env等。使用此安全正则表达式([A-z0-9-\+]+\/)*([A-z0-9-\.]+)(\?\d+$
      <?php
         public function fileStorageServe($file) {
                    // know you can have a mapping so you dont keep the sme names as in local (you can not precsise the same structor as the storage, you can do anything)
    
                    // any permission handling or anything else
    
                    // we check for the existing of the file 
                    if (!Storage::disk('local')->exists($filePath)){ // note that disk()->exists() expect a relative path, from your disk root path. so in our example we pass directly the path (/.../laravelProject/storage/app) is the default one (referenced with the helper storage_path('app')
                        abort('404'); // we redirect to 404 page if it doesn't exist
                    } 
                //file exist let serve it 
    
    // if there is parameters [you can change the files, depending on them. ex serving different content to different regions, or to mobile and desktop ...etc] // repetitive things can be handled through helpers [make helpers]
    
                    return response()->file(storage_path('app'.DIRECTORY_SEPARATOR.($filePath))); // the response()->file() will add the necessary headers in our place (no headers are needed to be provided for images (it's done automatically) expected hearder is of form => ['Content-Type' => 'image/png'];
    
    // big note here don't use Storage::url() // it's not working correctly.  
                }
    
    <?php
    public function getCompaniesLogo($file) {
        // know you can have a mapping so you dont keep the sme names as in local (you can not precsise the same structor as the storage, you can do anything)
    
        // any permission handling or anything else
    
        $filePath =  config('fs.gallery').DIRECTORY_SEPARATOR.$file; // here in place of just using 'gallery', i'm setting it in a config file
    
        // here i'm getting only the path from the root  (this way we can change the root later) / also we can change the structor on the store itself, change in one place config.fs.
    
        // $filePath = Storage::url($file); <== this doesn't work don't use
    
         // check for existance
        if (!Storage::disk('local')->exists($file)){ // as mentionned precise relatively to storage disk root (this one work well not like Storage:url()
              abort('404');
        } 
    
        // if there is parameters [you can change the files, depending on them. ex serving different content to different regions, or to mobile and desktop ...etc] // repetitive things can be handled through helpers [make helpers]
    
        return response()->file(storage_path('app'.DIRECTORY_SEPARATOR.($file))); // the response()->file() will add the necessary headers in our place
    }
    
    <img src="{{route('routeName', ['fileParam' => $storageRelativePath])}}" />
    
    <img src="{{route('routeName', ['fileName' => basename($storageRelativePath)])}}" />