如何在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萬個

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