如何在Laravel 中对大文件进行加密?

我将其称为 FileVault 包,您可以 GitHub 上查看它。 如果您想跳过本教程,可以直接转到 GitHub 存储库并开始使用此软件包。 该扩展包包括了详细的使用文档。

 

教程

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

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

1

laravel new security-app

  

 

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

 

1

php artisan key:generate

  

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

 

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

 

1

composer require laravel/ui — dev

  

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

1

php artisan ui bootstrap --auth

  

并编译所有内容:


注意:在本演示中,我们将创建一个基本的上传表单,但是在您的应用程序中,您应该考虑使用更复杂的上传功能,对大文件使用分块上传。现在,我们可以创建一个新用户并登录查看用户仪表板。  

 

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

 

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

 

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

 


然后添加相应的路由:  

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)) }}">

                {{ basename($file) }}

            </a>

        </li>

    @empty

        <li class="list-group-item">You have no files</li>

    @endforelse

</ul>

  

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

 

工信部:截至去年底 中国5G基站建设共13万个

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章