Laravel / Lumen 只读模型?

Posted

技术标签:

【中文标题】Laravel / Lumen 只读模型?【英文标题】:Laravel / Lumen ReadOnly Model? 【发布时间】:2020-12-23 17:03:33 【问题描述】:

我们的系统中有一些表是使用 3rd 方 API 提供的,我们的系统应该只从它们读取数据,从不插入或更新任何东西。

Laravel/Lumen 中是否有任何功能,我们可以在模型中提及禁止/禁用插入/更新查询,例如我们有选项 public $timestamps = false;禁用时间戳

这些表在同一个数据库中,否则我们会根据 mysql 用户进行限制。

【问题讨论】:

【参考方案1】:

也许在你的模型中使用一个空的可填充属性可以解决你的问题!

protected $fillable = [];

【讨论】:

【参考方案2】:

有几种方法。 选项 1:可能最快的是这个“只读”模型特征。 https://github.com/michaelachrisco/ReadOnlyTraitLaravel

它可以保护您免受...

创建 强制创建 保存 更新 firstOrCreate firstOrNew 删除 销毁 恢复 强制删除 执行DeleteOnModel 推 完成保存 执行更新 触摸 插入 截断

选项 2:完全不同的方式是在数据库配置和模型连接上。所以,这有 2 个部分。

项目/配置/数据库.php 复制并调整数据库连接。

'mysql' => [
            'driver'         => 'mysql',
            'host'           => env('DB_HOST', '127.0.0.1'),
    ...
'readonly' => [
            'driver'         => 'mysql',
            'read' => [
                'host' => env('DB_HOST', '127.0.0.1')
            ],
            'write' => [
                'host' => 'this.will.404'
            ],
    ...

项目/app/MyReadOnlyModel.php

class MyReadOnlyModel extends Model

    protected $connection  = 'readonly';
...

如果您陷入了希望模型有时可写的陷阱……我建议在同一张桌子上放置 2 个模型。

app/Normal/MyModel.php

app/ReadOnly/MyModel.php

【讨论】:

【参考方案3】:

    创建一个具有只读权限的附加 mySql 用户。

    在 .env 文件中添加以下内容

    DB_CONNECTION_SECOND=mysql

    DB_HOST_SECOND=127.0.0.1

    DB_PORT_SECOND=3306

    DB_DATABASE_SECOND=数据库

    DB_USERNAME_SECOND=user_2

    DB_PASSWORD_SECOND=秘密

    在 config/database.php 添加以下内容

    'mysql2' => [
    'driver'    => env('DB_CONNECTION_SECOND'),
    'host'      => env('DB_HOST_SECOND'),
    'port'      => env('DB_PORT_SECOND'),
    'database'  => env('DB_DATABASE_SECOND'),
    'username'  => env('DB_USERNAME_SECOND'),
    'password'  => env('DB_PASSWORD_SECOND'),],
    

    在您的控制器中指定连接名称..

    DB::connection('mysql2')->select(...);

【讨论】:

【参考方案4】:

我认为管理此问题的唯一正确方法是在 MySQL 用户端设置访问限制。原因如下:

如果您从 Eloquent 类中存根(禁用)保存/更新方法,您只需禁用您自己代码的保存/更新。这类似于将钥匙挂在门把手上时锁门。没有什么可以阻止您进行保存/更新,因为您不必使用 Eloquent 类。

此外,第 3 方包可能会保留不依赖于您的代码的数据。您基本上必须检查他们的每一行代码以确保您的数据库没有更新。

因此,在数据库用户级别应用这些限制。然后,当出于某种原因您(或其他任何人)代码调用$myModel->save() 时,您应该面临来自 ORM 的异常,指出您没有权限。然后,相应地处理它(比如返回一个特定的 HTTP 状态代码)。

【讨论】:

【参考方案5】:

是的,

作为一种安全的方式:

因为您可以限制对数据库的某些操作。

只读模型

但您也可以禁用 eloquent 模型。

laravel 模型扩展自 Illuminate\Database\Eloquent\Model

您可以从 Model 扩展 ReadOnlyModel。

然后从该类扩展您想要的任何模型。

这个类应该覆盖任何将数据写入数据库的方法,

所以我遵循源代码:

Update 和 updateOrFail、push 等使用了 Model->save() 方法。

虽然 create,creteOrFail , delete 等是在使用 Model->save() 方法的 Builder 中的地方

save() 方法使用了 performUpdate 或 performInsert 并触发了一些事件...

所以阻止模型接触数据库的最简单方法是实现:

   <?php

namespace App\ReadOnlyDB;

use Illuminate\Database\Eloquent\Model;
/**
* Just Extend all of Your Models from This Class
*
*/
class ReadOnlyModel extends Model

        public function save()
            // do nothing
        

Relation 和 BelongsTo 类中的 save() 方法也会使用 Model->save() 方法。

【讨论】:

您还需要覆盖 update() 方法,可能还有其他方法,具体取决于您的需要。这里有很多可能性:github.com/michaelachrisco/ReadOnlyTraitLaravel/blob/main/src/… @joelMellon 更新方法使用save() method itself。 IDK,全部覆盖!【参考方案6】:

最安全的方法是使用readonly only on the tables 创建第二个 MySQL 用户。 然后在 Laravel 中,您可以在 config/database.php 中创建与受限 MySQL 用户的特定连接。 然后在模型中通过protected $connection 属性指定想要的连接。

【讨论】:

以上是关于Laravel / Lumen 只读模型?的主要内容,如果未能解决你的问题,请参考以下文章

如何在接收事件的多个 Laravel/Lumen 侦听器中保留模型状态?

Auth 尝试方法在 Laravel/Lumen + JWT + 用户自定义模型中如何工作

Lumen/laravel Event Demo

Laravel/lumen 5.2 从现有数据库生成迁移表

Laravel 和 Lumen ACL 与共享代码库

Lumen (Laravel) Eloquent php artisan make:model 未定义