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

我已经搜索过用于解决此问题的软件包或解决方案,并遇到了这个 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 文件并添加一个表单和一个上传字段:

<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>

然后添加相应的路由:

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

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

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

<?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 方法现在的样子:

<?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 方法:

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, 接收一个回调.

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

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

<?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>

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

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

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

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

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

(0)

相关推荐

  • Laravel统一封装接口返回状态实例讲解

    前后端分离,接口返回封装方便你我他(方便前后端合作开发) 在Laravel中可以在公共继承的Controller.php写方法进行调用返回 app/Http/Controllers/Controller.php 成功返回 /** * $msg 返回提示消息 * $data 返回数据 */ public function success($msg,$data = []) { return response()->json([ 'status' => true, 'code' => 200,

  • Laravel的加密解密与哈希实例讲解

    一.加密解密 当你的应用程序中需要用到加密和解密的地方时可以使用Laravel自带的加密解密工具. Laravel 的加密机制使用的是 OpenSSL 所提供的 AES-256 和 AES-128 加密.强烈建议你使用 Laravel 内建的加密工具,而不是用其它的加密算法.所有 Laravel 加密之后的结果都会使用消息认证码 (MAC) 签名,使其底层值不能在加密后再次修改. 相应的配置文件 config/app.php 首先生成 APP_KEY php artisan key:genera

  • laravel 5.3中自定义加密服务的方案详解

    前言 本文介绍的是laravel 5.3中自定义加密服务的方案,利用laravel的服务容器,实现自定义加密服务注册(示例是支持长字符串的RSA加密),下面来看看详细的介绍: 创建加密解密服务类 文件地址 /app/Service/Common/CryptService.php 代码如下 下面这个是个人写的支持长字符串的RSA加密类作为示例,自定义加密的话只需更改这个文件的代码就好,其它操作只是为了实现依赖注入. <?php namespace App\Service\Common; class

  • Laravel 数据库加密及数据库表前缀配置方法

    报错问题:DecryptException in Encrypter.php line 148: The MAC is invalid. 如何运行 php artisan key:generate 这个命令 需要安装Composer D: 回到D盘 ,cd 到laravel根目录 然后运行 php artisan key:generate:前提是你项目根目录下有个.env文件,如果没有,敲命令 "echo 内容 >.env",生成一个.env 文件(不带引号哦),然后把根路径下的

  • Laravel 重写日志,让日志更优雅

    更改目的: 重写了日志格式 加入trace,一次请求的唯一标识 加入error级别信息推送,事例中使用企业微信群助手 让我们可以更及时.更优雅.更方便追踪日志信息 有助于初学者了解Laravel框架 1.将文件 AppTool.php.Logger.php.LogServiceProvider.php复制到 app/Providers文件夹下,将文件BaseCommand.php复制到App\Console下 2 .在config/app.php→providers中加入 'providers'

  • Laravel中的where高级使用方法实例讲解

    有时候项目中需要进行多个字段搜索就可以用到此方法 在Laravel中的可以同时使用多个where,所以我们可以每个字段分配一个where() 然后在每个where()中去闭包判断 $username = '';// 收货人姓名 $hospital_id = ''; // 医院id # 判断是否有姓名搜索 if (!empty($request->username)) { $username = $request->username; } # 判断是否有医院搜索 if (!empty($requ

  • laravel使用组件实现微信网页授权登入

    laravel框架中的实现简单实现微信网页授权登入 首先引入基于laravel的easywechat的组件,laravel版本5.8 $ cd laravel $ composer require "overtrue/laravel-wechat:~5.0" 参考组件地址:https://github.com/overtrue/laravel-wechat 然后呢因为下载过程会比较缓慢所以可以先根据官方提供的方式配置一下该组件的中间件 根据官方提供的测试代码在routes/web.ph

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

    我已经搜索过用于解决此问题的软件包或解决方案,并遇到了这个 Stack Overflow 回答和这个 PHP 解决方案,该解决方案基本上是 Stack Overflow 所描述的解决方案的 PHP 实现. 我决定创建一个为 Laravel 设计的扩展包,使用简单,优雅的语法提供简单的文件加密 / 解密功能. 在这个教程中,我会详细描述加密大文件需要的所有步骤. 首先, 使用 Laravel 安装器创建一个新的 Laravel 项目, 命名为security-app: laravel new se

  • 浅谈Laravel中使用Slack进行异常通知

    概述 通常,我们可以依靠用户反馈.经常查看程序日志来发现程序存在的问题.但这要么不可靠要么不及时,所以下面我们介绍一种比较有效的做法--使用 Slack 通知程序跑出的异常信息. Slack 是一款即时通信软件,类似于 QQ,它提供开放的 API,可以调用它向自己团队中指定的个人或者频道(Channel)发送消息,因此用它来进行异常通知是再合适不过的. 安装 maknz/slack-laravel 包 具体的安装方法请参考 Github 上的 [readme](https://github.co

  • 浅谈JavaScript中小数和大整数的精度丢失

    先来看两个问题: 0.1 + 0.2 == 0.3; // false 9999999999999999 == 10000000000000000; // true 第一个问题是小数的精度问题,在业界不少博客里已有讨论.第二个问题,去年公司有个系统的数据库在做数据订正时,发现有部分数据重复的诡异现象.本文将从规范出发,对上面的问题做个小结. 最大整数 JavaScript 中的数字是用 IEEE 754 双精度 64 位浮点数 来存储的,其格式为: s x m x 2^e s 是符号位,表示正负

  • 浅谈laravel中的关联查询with的问题

    表结构 主表结构: Create Table CREATE TABLE `user` ( `uid` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, `email` varbinary(255) NOT NULL, PRIMARY KEY (`uid`) ) ENGINE=InnoDB AUTO_INCREMENT=114001 DEFA

  • 浅谈Laravel中的三种中间件的作用

    在之前一直简单的认为中间件就是往middleware里添加中间件即可.现在才知道中间件有三种类型,分别为:$middleware $middlewareGroup $routeMiddleware 通过查阅资料,终于明白了这三种类型的作用和不同. 第一种,全局中间件/$middleware: 我们的每一次请求,这里面的每个中间件都会执行. 第二种,路由中间件/$routeMiddleware: 定义在该属性内的中间件,只能在定义路由的时候引用. 假设这是我们定义的路由中间件: protected

  • 浅谈Laravel中的一个后期静态绑定

    关于 PHP  的 new static 延迟静态绑定,或者叫后期静态绑定,在 Laravel 中遇到一个使用上的问题.如下,在 Laravel 中调用 Model 新增数据的时候,首先给 Model 加了一个获取分表的方法: protected function addToMessage($msgType, $userID, $commentID, $replyCommentID, $replyUserID, $gameID) { if (!$userID) { return false; }

  • 浅谈C#中Md5和Sha1两种加密方式

    1.新建控制台应用程序 2.新建类 EncryptHelper.cs public static class EncryptHelper { /// <summary> /// 基于Md5的自定义加密字符串方法:输入一个字符串,返回一个由32个字符组成的十六进制的哈希散列(字符串). /// </summary> /// <param name="str">要加密的字符串</param> /// <returns>加密后的十六

  • 浅谈php中fopen不能创建中文文件名文件的问题

    之前网页的chartset用的是utf-8,文件也用utf-8,然后用fopen()创建一个中文文件名的文件时问题就出来了,文件名都是乱 码! 查看了很多文档试了不少方法都解决不了,本来想着用别的方法绕过这个问题,忽然脑子里闪过Windows默认的文字编码是ansi,然后再 baidu了一下,证实了这点,所以我的网页也应该是ansi编码才能使创建的文件名不会是乱码. 接着就着手验证,把网页都用ansi保存,去掉chartset语句,果然ok了,但是网页的内容就成乱码了,后来想起,这个网页还inc

  • 浅谈JavaWeb中的web.xml配置部署描述符文件

    1. 定义头和根元素 部署描述符文件就像所有XML文件一样,必须以一个XML头开始.这个头声明可以使用的XML版本并给出文件的字符编码. DOCYTPE声明必须立即出现在此头之后.这个声明告诉服务器适用的servlet规范的版本(如2.2或2.3)并指定管理此文件其余部分内容的语法的DTD(Document Type Definition,文档类型定义). 所有部署描述符文件的顶层(根)元素为web-app.请注意,XML元素不像HTML,他们是大小写敏感的.因此,web-App和WEB-APP

  • 浅谈VS中添加头文件时显示无法找到文件的问题

    目录或库文件名中包含汉字或空格的话,请将其用半角双引号括住. 项目.属性.C/C++.附加包含目录:填写附加头文件所在目录 分号间隔多项 项目.属性.链接器.附加库目录:填写附加依赖库所在目录 分号间隔多项 项目.属性.链接器(点前面的+展开).输入.附加依赖项:填写附加依赖库的名字.lib 空格间隔多项 这样在我们添加现有项后,经常出现的找不到源文件等等问题就解决了 以上这篇浅谈VS中添加头文件时显示无法找到文件的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们

随机推荐