You need to enable JavaScript to run this app. Laravel 8 API 如何将JWTAuth认证用户ID填充为帖子user_id字段
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 8 API 如何将JWTAuth认证用户ID填充为帖子user_id字段

报错根因

触发1364错误的核心原因是新增帖子的SQL语句缺失user_id字段赋值:

  • 当前代码直接拿全量请求参数$request->all()传给Post::create(),既没有从认证上下文取当前登录用户的ID做自动赋值,也没有隔离前端可能恶意传入的user_id、likes这类敏感字段
  • posts表的user_id是非空无默认值的字段,插入时缺值就会触发数据库报错
  • 原代码还存在两处隐藏逻辑问题:
    • 标题唯一性校验规则的表名写错:unique:categories是校验分类表的字段唯一性,和帖子表无关
    • tags校验规则null|string逻辑存在漏洞:当tags入参为null时,后续explode(",", $request->tags)会触发PHP运行时错误
安全修正方案
  1. 先做好模型批量赋值防护
    在Post模型中配置$fillable白名单,仅允许指定字段被批量赋值:

    // app/Models/Post.php
    protected $fillable = [
        'category_id',
        'title',
        'body',
        'picture',
        'study_time',
        'tags',
        'user_id', // 仅用于手动赋值,不会从前端入参读取
    ];
    
  2. 改造store方法逻辑,彻底隔绝越权入参风险
    不使用$request->all()全量取数,主动只拉取业务允许前端传入的字段,再从JWTAuth认证上下文取当前用户ID手动赋值,从根源上杜绝前端篡改user_id、likes这类敏感字段的可能。修正后完整代码如下:

    // 仅提取前端允许传入的字段,自动过滤掉user_id、likes、id这类敏感参数
    $data = $request->safe()->only([
        'category_id',
        'title',
        'body',
        'picture',
        'study_time',
        'tags'
    ]);
    
    $validator = Validator::make($data, [
        'category_id' => 'required|exists:categories,id',
        'title' => 'required|max:100|unique:posts', // 修正原规则的表名错误
        'body' => 'required',
        'picture' => 'required',
        'study_time' => 'required',
        'tags' => 'nullable|string', // 用Laravel内置nullable规则替代原null|string的写法
    ]);
    
    if ($validator->fails()) {
        return response()->json([
            'error' => $validator->errors(),
            'msg' => 'Validation Error'
        ], 422);
    }
    
    // 从认证上下文获取用户ID,完全不受前端请求参数影响
    $data['user_id'] = JWTAuth::user()->id;
    
    // 处理标签逻辑,兼容tags为空的场景
    $tags = $request->tags ? explode(",", $request->tags) : [];
    
    $post = Post::create($data);
    $post->tag($tags);
    
    return response()->json([
        'username' => JWTAuth::user()->username,
        'post' => $post
    ], 201);
    
  3. 效果说明
    就算前端在请求里恶意传入user_id=1(管理员账号ID)、likes=10000这类参数,因为我们只通过only()拉取业务允许的字段,这些恶意参数根本不会进入最终的数据库写入流程,完全实现user_id自动赋值、隔绝前端篡改的目标。


内容的提问来源于stack exchange,提问作者calisa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.29 01:15:01