跳转到主内容
极星编程网:以代码为星,赴技术山海!

PHP怎么处理Eloquent Attribute Authentication属性认证_Laravel证明数据来源【指南】

Eloquent没有Attribute Authentication机制,它只是对访问器、Mutator等的误称;真正可信的数据来源是经中间件验证的Auth::user()或token解析结果。 Attribute Authentication不是Eloquent内置功能 PHP里没有叫
Attribute Authentication
的Eloquent原生机制,Laravel官方文档和源码中也不存在这个术语。你看到的可能是对
get*
/
set*
访问器、
$casts
、
$appends
或者自定义属性逻辑的误称,也可能是第三方包(如
laravel-attribute-auth
)的非标准命名。直接搜这个短语,90%会掉进概念混淆的坑。 真正能“证明数据来源”的,是以下几种可落地的方式:
Auth::user()
或
auth()->id()
—— 用于记录创建/修改人 数据库触发器 +
current_user()
(PostgreSQL)或
USER()
(MySQL)—— 服务端强制留痕 模型事件(
creating
,
updating
)中手动填充
created_by
/
updated_by
字段 使用 Laravel Sanctum / Passport 的 token scope + 中间件做请求级来源校验 如何用访问器+Mutator实现“可信属性”逻辑 如果你希望某个字段(比如
is_verified
)只能由系统规则变更、不能被用户直接提交,就别依赖前端传值,而应通过访问器控制读、Mutator控制写。 示例:一个只允许管理员或后台任务设为
true
的认证标记: 立即学习 “ PHP免费学习笔记(深入) ”;
class User extends Model { protected $fillable = ['name', 'email']; // 不允许 mass assignment 写入 verified_at protected $guarded = ['verified_at']; // 读取时返回布尔值,但不暴露原始字段 public function getIsVerifiedAttribute() { return !is_null($this->verified_at); } // 写入时拦截,仅允许特定上下文调用 public function setIsVerifiedAttribute($value) { if (!in_array(\App::environment(), ['local', 'testing']) && !\Auth::check() && !\App::runningInConsole()) { throw new \Exception('Direct assignment to is_verified is forbidden'); } $this->attributes['verified_at'] = $value ? now() : null; } }
注意:
setIsVerifiedAttribute
不会在
fill()
或
update()
中自动触发,除非你显式赋值
$user->is_verified = true
;批量更新(
User::where(...)->update([...])
)完全绕过它。 Eloquent事件比访问器更适合做来源审计 想留下“谁在什么时候因为什么改了这个字段”,靠访问器做不到。必须用模型事件,在数据库操作前/后打日志或写审计表。 PHP 8.5.5 PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。 下载 推荐做法: 监听
updating
事件,检查
$model->isDirty('email')
和
auth()->id()
把变更前值、后值、操作人ID、IP、User-Agent 存进
audit_logs
表 避免在事件里做耗时操作(如发邮件),改用队列 禁用
timestamps
的模型要手动补
updated_at
,否则事件里
$model->wasChanged()
可能失效 关键点:Eloquent事件运行在 PHP 层,无法防止直接 SQL 更新(如
DB::table(...)->update(...)
)。真要防死,得上数据库行级安全策略(RLS)或触发器。 Token认证才是真正的“数据来源证明”入口 前端传来的任何字段(包括伪装成
created_by
的 ID)都不可信。唯一可信的数据来源,是经过中间件验证后的
Auth::user()
或
request()->bearerToken()
解析结果。 所以实际链路应该是: 请求带
Authorization: Bearer xxx
经
auth:sanctum
中间件解出用户 控制器里用
$request->user()->id
填充
created_by
,而不是信任
$request->input('created_by')
数据库字段设为
NOT NULL
,迁移里加
$table->foreignId('created_by')->constrained()->cascadeOnDelete();
漏掉中间件、或在模型里用
Auth::id()
而非
$request->user()
,会导致 CLI 或队列任务中获取到错误用户 ID —— 这是最常被忽略的上下文陷阱。

相关文章