浅谈Laravel中如何对大文件进行加密

吾爱主题 阅读:128 2021-11-17 16:04:00 评论:0

我已经搜索过用于解决此问题的软件包或解决方案,并遇到了这个 Stack Overflow 回答和这个 PHP 解决方案,该解决方案基本上是 Stack Overflow 所描述的解决方案的 PHP 实现。

我决定创建一个为 Laravel 设计的扩展包,使用简单,优雅的语法提供简单的文件加密 / 解密功能。

在这个教程中,我会详细描述加密大文件需要的所有步骤。

首先, 使用 Laravel 安装器创建一个新的 Laravel 项目, 命名为security-app:

laravel new security-app

在撰写本教程时,我正在使用 Laravel v6.5.2。

因为我们已经使用了 Laravel 安装程序,所以我们已经生成了一个应用程序密钥并将其添加到我们的 .env 文件中。 如果您使用其他安装方法,请不要忘记使用以下方法生成新的应用程序密钥:

php artisan key:generate

因为我们正在使用 Laravel Valet,所以应该已经为我们创建了 security-app.test 域名。 如果使用其他开发环境,则应添加一个本地域名指向新项目。

由于自 Laravel 6 以来前端脚手架已被移至 Laravel UI 中,因此我们将安装 laravel/ui 扩展包。

composer require laravel/ui — dev

接下来,我们将安装bootstrap和auth脚手架:

php artisan ui bootstrap --auth

并编译所有内容:

npm install && npm run dev

我们还需要在 .env 文件中配置数据库访问凭据并运行初始迁移:

php artisan migrate

现在,我们可以创建一个新用户并登录查看用户仪表板。

注意:在本演示中,我们将创建一个基本的上传表单,但是在您的应用程序中,您应该考虑使用更复杂的上传功能,对大文件使用分块上传。

您可以使用一个非常好的扩展包是 pion/laravel-chunk-upload.

Laravel Auth 脚手架为我们创建了一个 /home 路由,一个 HomeController 和一个 home.blade.php 视图文件。

让我们编辑 home.blade.php 文件并添加一个表单和一个上传字段:

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <form action= "{{ route('uploadFile') }}" method= "post" enctype= "multipart/form-data" class = "my-4" >      @csrf        <div class = "form-group" >          <div class = "custom-file" >              <input type= "file" class = "custom-file-input" id= "userFile" name= "userFile" >              <label class = "custom-file-label" for = "userFile" >Choose a file</label>          </div>      </div>        <button type= "submit" class = "btn btn-primary" >Upload</button>        @ if (session()->has( 'message' ))          <div class = "alert alert-success mt-3" >              {{ session( 'message' ) }}          </div>      @ endif </form>

然后添加相应的路由:

?
1 Route::post(‘/home ', ‘HomeController@store' )->name(‘uploadFile');

在 HomeController 中新增 store 方法。 此方法会将上传的文件存储在具有当前用户 ID 的文件目录中 (storage/app/files/{user-id}) 。

注意:这是不正确的做法,不应在生产环境中使用。 为了使本教程更加小巧,我们使用文件系统来获取用户的文件,但是在生产环境中,需要使用数据库来跟踪每个用户上传的文件。

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?php     /**       * Store a user uploaded file       *       * @param  \Illuminate\Http\Request $request       * @return \Illuminate\Http\Response       */      public function store(Request $request )      {          if ( $request ->hasFile( 'userFile' ) && $request ->file( 'userFile' )->isValid()) {              Storage::putFile( 'files/' . auth()->user()->id, $request ->file( 'userFile' ));          }            return redirect()->route( 'home' )->with( 'message' , 'Upload complete' );      }

到了加密用户上传文件的阶段。我们将安装file-vault扩展包:

composer require soarecostin/file-vault

该软件包允许访问 FileVault 门面, 其中提供了一些用于加密和解密文件的方法,还提供了一些方法来设置选项,例如为每个文件设置不同的加密密钥,或指定该文件的 Laravel 文件系统磁盘。

我们将使用 FileVault::encrypt($file) 方法来加密用户上传的文件。 此功能将删除原始的未加密文件,并将其替换为具有相同名称和附加 .enc 扩展名的文件。

如果您想使用不同的名称命名文件,则可以将所需的名称作为第二个参数传递给 encrypt 方法。 如果您想保留原始文件,可以使用 encryptCopy 方法。

这就是我们的 store 方法现在的样子:

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <?php      /**       * Store a user uploaded file       *       * @param  \Illuminate\Http\Request $request       * @return \Illuminate\Http\Response       */      public function store(Request $request )      {          if ( $request ->hasFile( 'userFile' ) && $request ->file( 'userFile' )->isValid()) {              $filename = Storage::putFile( 'files/' . auth()->user()->id, $request ->file( 'userFile' ));                // Check to see if we have a valid file uploaded              if ( $filename ) {                  FileVault::encrypt( $filename );              }          }            return redirect()->route( 'home' )->with( 'message' , 'Upload complete' );      }

接下来,我们需要查看所有用户上传的文件,还需要一种下载它们的方法。

我们将在 HomeController 中创建一个新的 downloadFile 路由和一个新的 downloadFile 方法:

?
1 Route::get(‘/files/{filename} ', ‘HomeController@downloadFile' )->name(‘downloadFile');
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?php      /**       * Download a file       *       * @param  string  $filename       * @return \Illuminate\Http\Response       */      public function downloadFile( $filename )      {          // Basic validation to check if the file exists and is in the user directory          if (!Storage::has( 'files/' . auth()->user()->id . '/' . $filename )) {              abort(404);          }            return response()->streamDownload( function () use ( $filename ) {              FileVault::streamDecrypt( 'files/' . auth()->user()->id . '/' . $filename );          }, Str::replaceLast( '.enc' , '' , $filename ));      }

downloadFile 使用 Laravel 原生的 streamDownload response, 接收一个回调.

在回调中,我们正在调用扩展包 FileVault 提供的 streamDecrypt 方法,它将对文件进行解密并将其逐段提供给streamDownload方法,从而允许您的用户直接下载解密文件。

现在,我们需要在上传表单下方显示所有用户的文件。 为此,我们将 $files 变量从 HomeController 的 index 方法发送到 home.blade.php 视图文件,并在上传表格的下面显示用户文件。

?
1 2 3 4 5 6 7 8 9 10 11 12 13 <?php        /**       * Show the application dashboard.       *       * @return \Illuminate\Contracts\Support\Renderable       */      public function index()      {          $files = Storage::files( 'files/' . auth()->user()->id);            return view( 'home' , compact( 'files' ));      }

home.blade.php

?
1 2 3 4 5 6 7 8 9 10 11 <ul class = "list-group" >      @forelse ( $files as $file )          <li class = "list-group-item" >              <a href= "{{ route('downloadFile', basename($file)) }}" rel= "external nofollow" >                  {{ basename ( $file ) }}              </a>          </li>      @ empty          <li class = "list-group-item" >You have no files</li>      @endforelse </ul>

就是这样! 我们现在在使用静态加密! 我们创建了供用户上传文件的表单,对这些文件进行加密,并且仅在上传文件的用户要求时才对其解密。

当然,在生产中,需要采取更多的安全措施,而 FileVault 扩展包旨在这方面为您提供帮助。

如,您可能希望将用户上传的大文件存储在 Amazon S3 中,该扩展包支持文件加密 / 流解密。

您可能还想为每个用户或每个文件使用不同的加密密钥,这对于 FileVault 扩展包也是可能的。

以上就是浅谈Laravel中如何对大文件进行加密的详细内容,更多关于Laravel中如何对大文件进行加密的资料请关注服务器之家其它相关文章!

原文链接:https://www.cnblogs.com/a609251438/p/12659699.html

可以去百度分享获取分享代码输入这里。
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

【腾讯云】云服务器产品特惠热卖中
搜索
标签列表
    关注我们

    了解等多精彩内容