淺談Laravel中如何對(duì)大文件進(jìn)行加密
我已經(jīng)搜索過(guò)用于解決此問(wèn)題的軟件包或解決方案,并遇到了這個(gè) Stack Overflow 回答和這個(gè) PHP 解決方案,該解決方案基本上是 Stack Overflow 所描述的解決方案的 PHP 實(shí)現(xiàn)。
我決定創(chuàng)建一個(gè)為 Laravel 設(shè)計(jì)的擴(kuò)展包,使用簡(jiǎn)單,優(yōu)雅的語(yǔ)法提供簡(jiǎn)單的文件加密 / 解密功能。
在這個(gè)教程中,我會(huì)詳細(xì)描述加密大文件需要的所有步驟。
首先, 使用 Laravel 安裝器創(chuàng)建一個(gè)新的 Laravel 項(xiàng)目, 命名為security-app:
laravel new security-app
在撰寫(xiě)本教程時(shí),我正在使用 Laravel v6.5.2。
因?yàn)槲覀円呀?jīng)使用了 Laravel 安裝程序,所以我們已經(jīng)生成了一個(gè)應(yīng)用程序密鑰并將其添加到我們的 .env 文件中。 如果您使用其他安裝方法,請(qǐng)不要忘記使用以下方法生成新的應(yīng)用程序密鑰:
php artisan key:generate
因?yàn)槲覀冋谑褂?Laravel Valet,所以應(yīng)該已經(jīng)為我們創(chuàng)建了 security-app.test 域名。 如果使用其他開(kāi)發(fā)環(huán)境,則應(yīng)添加一個(gè)本地域名指向新項(xiàng)目。
由于自 Laravel 6 以來(lái)前端腳手架已被移至 Laravel UI 中,因此我們將安裝 laravel/ui 擴(kuò)展包。
composer require laravel/ui — dev
接下來(lái),我們將安裝bootstrap和auth腳手架:
php artisan ui bootstrap --auth
并編譯所有內(nèi)容:
npm install && npm run dev
我們還需要在 .env 文件中配置數(shù)據(jù)庫(kù)訪問(wèn)憑據(jù)并運(yùn)行初始遷移:
php artisan migrate
現(xiàn)在,我們可以創(chuàng)建一個(gè)新用戶(hù)并登錄查看用戶(hù)儀表板。
注意:在本演示中,我們將創(chuàng)建一個(gè)基本的上傳表單,但是在您的應(yīng)用程序中,您應(yīng)該考慮使用更復(fù)雜的上傳功能,對(duì)大文件使用分塊上傳。
您可以使用一個(gè)非常好的擴(kuò)展包是 pion/laravel-chunk-upload.
Laravel Auth 腳手架為我們創(chuàng)建了一個(gè) /home 路由,一個(gè) HomeController 和一個(gè) home.blade.php 視圖文件。
讓我們編輯 home.blade.php 文件并添加一個(gè)表單和一個(gè)上傳字段:
<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>
然后添加相應(yīng)的路由:
Route::post(‘/home', ‘HomeController@store')->name(‘uploadFile');
在 HomeController 中新增 store 方法。 此方法會(huì)將上傳的文件存儲(chǔ)在具有當(dāng)前用戶(hù) ID 的文件目錄中 (storage/app/files/{user-id}) 。
注意:這是不正確的做法,不應(yīng)在生產(chǎn)環(huán)境中使用。 為了使本教程更加小巧,我們使用文件系統(tǒng)來(lái)獲取用戶(hù)的文件,但是在生產(chǎn)環(huán)境中,需要使用數(shù)據(jù)庫(kù)來(lái)跟蹤每個(gè)用戶(hù)上傳的文件。
<?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'); }
到了加密用戶(hù)上傳文件的階段。我們將安裝file-vault擴(kuò)展包:
composer require soarecostin/file-vault
該軟件包允許訪問(wèn) FileVault 門(mén)面, 其中提供了一些用于加密和解密文件的方法,還提供了一些方法來(lái)設(shè)置選項(xiàng),例如為每個(gè)文件設(shè)置不同的加密密鑰,或指定該文件的 Laravel 文件系統(tǒng)磁盤(pán)。
我們將使用 FileVault::encrypt($file) 方法來(lái)加密用戶(hù)上傳的文件。 此功能將刪除原始的未加密文件,并將其替換為具有相同名稱(chēng)和附加 .enc 擴(kuò)展名的文件。
如果您想使用不同的名稱(chēng)命名文件,則可以將所需的名稱(chēng)作為第二個(gè)參數(shù)傳遞給 encrypt 方法。 如果您想保留原始文件,可以使用 encryptCopy 方法。
這就是我們的 store 方法現(xiàn)在的樣子:
<?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'); }
接下來(lái),我們需要查看所有用戶(hù)上傳的文件,還需要一種下載它們的方法。
我們將在 HomeController 中創(chuàng)建一個(gè)新的 downloadFile 路由和一個(gè)新的 downloadFile 方法:
Route::get(‘/files/{filename}', ‘HomeController@downloadFile')->name(‘downloadFile');
<?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, 接收一個(gè)回調(diào).
在回調(diào)中,我們正在調(diào)用擴(kuò)展包 FileVault 提供的 streamDecrypt 方法,它將對(duì)文件進(jìn)行解密并將其逐段提供給streamDownload方法,從而允許您的用戶(hù)直接下載解密文件。
現(xiàn)在,我們需要在上傳表單下方顯示所有用戶(hù)的文件。 為此,我們將 $files 變量從 HomeController 的 index 方法發(fā)送到 home.blade.php 視圖文件,并在上傳表格的下面顯示用戶(hù)文件。
<?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
<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>
就是這樣! 我們現(xiàn)在在使用靜態(tài)加密! 我們創(chuàng)建了供用戶(hù)上傳文件的表單,對(duì)這些文件進(jìn)行加密,并且僅在上傳文件的用戶(hù)要求時(shí)才對(duì)其解密。
當(dāng)然,在生產(chǎn)中,需要采取更多的安全措施,而 FileVault 擴(kuò)展包旨在這方面為您提供幫助。
如,您可能希望將用戶(hù)上傳的大文件存儲(chǔ)在 Amazon S3 中,該擴(kuò)展包支持文件加密 / 流解密。
您可能還想為每個(gè)用戶(hù)或每個(gè)文件使用不同的加密密鑰,這對(duì)于 FileVault 擴(kuò)展包也是可能的。
以上就是淺談Laravel中如何對(duì)大文件進(jìn)行加密的詳細(xì)內(nèi)容,更多關(guān)于Laravel中如何對(duì)大文件進(jìn)行加密的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
PHP 優(yōu)化配置——加速你的VBB,phpwind,Discuz,IPB,MolyX
PHP 優(yōu)化配置——加速你的VBB,phpwind,Discuz,IPB,MolyX...2007-07-07WordPress中重置文章循環(huán)的rewind_posts()函數(shù)講解
這篇文章主要介紹了WordPress中的文章循環(huán)重置函數(shù)rewind_posts()講解,附帶不依賴(lài)循環(huán)的single_cat_title()函數(shù)的用法介紹,需要的朋友可以參考下2016-01-01php回調(diào)函數(shù)處理數(shù)組操作示例
這篇文章主要介紹了php回調(diào)函數(shù)處理數(shù)組操作,結(jié)合實(shí)例形式詳細(xì)分析了PHP回調(diào)函數(shù)遍歷與過(guò)濾數(shù)組相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下2020-04-04php基于mcrypt_encrypt和mcrypt_decrypt實(shí)現(xiàn)字符串加密解密的方法
這篇文章主要介紹了php基于mcrypt_encrypt和mcrypt_decrypt實(shí)現(xiàn)字符串加密解密的方法,結(jié)合實(shí)例形式分析了mcrypt_encrypt和mcrypt_decrypt函數(shù)進(jìn)行加密、解密的相關(guān)使用技巧,需要的朋友可以參考下2016-07-07PHP JSON出錯(cuò):Cannot use object of type stdClass as array解決方法
這篇文章主要介紹了PHP JSON出錯(cuò):Cannot use object of type stdClass as array解決方法,需要的朋友可以參考下2014-08-08關(guān)于php 高并發(fā)解決的一點(diǎn)思路
涉及搶購(gòu)、秒殺、抽獎(jiǎng)、搶票等活動(dòng)時(shí),為了避免超賣(mài),那么庫(kù)存數(shù)量是有限的,但是如果同時(shí)下單人數(shù)超過(guò)了庫(kù)存數(shù)量,就會(huì)導(dǎo)致商品超賣(mài)問(wèn)題。那么我們?cè)趺磥?lái)解決這個(gè)問(wèn)題呢,我的思路如下2017-04-04