You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel用户权限控制:如何限制非团队成员查看对应问卷?

嘿,这个越权漏洞确实得赶紧修复,我给你几个实用的实现方案,都是Laravel项目里常用的做法,你可以根据自己的项目规模选:

修复问卷权限越权漏洞的实现方案

核心逻辑很明确:只有问卷所属团队的成员才能查看该问卷,所以我们需要先打通用户、团队、问卷三者的关联,再在访问时做权限校验。

1. 先确认数据库关联(如果还没配置的话)

假设你的数据库里有这几张表:

  • surveys:问卷表,需要新增team_id字段关联到teams表的主键
  • teams:团队表
  • user_team:用户-团队关联表(多对多),包含user_id和team_id两个字段

对应的模型关系也要配置好:

// Survey.php 模型
public function team()
{
    return $this->belongsTo(Team::class);
}

// Team.php 模型
public function users()
{
    return $this->belongsToMany(User::class);
}

// User.php 模型
public function teams()
{
    return $this->belongsToMany(Team::class);
}

2. 方案一:控制器内直接校验(快速修复)

适合小型项目或者临时快速修复,直接在你的viewSurvey方法里加入校验逻辑:

public function viewSurvey($id)
{
    // 先找到目标问卷,找不到直接返回404
    $survey = Survey::findOrFail($id);
    
    // 获取当前登录用户(确保路由已加auth中间件,拦截未登录访问)
    $currentUser = auth()->user();
    
    // 用exists查询校验用户是否属于问卷所属团队,比加载全部用户更高效
    $hasPermission = $survey->team->users()->where('user_id', $currentUser->id)->exists();
    
    if (!$hasPermission) {
        // 无权限时返回403禁止访问,也可以跳转到自定义错误页面
        abort(403, '你没有权限查看该问卷');
    }
    
    // 权限通过,继续执行原有业务逻辑
    $object = DB::table('question')->where('survey_id', '=', $id)->get();
    $date = Sur... // 你的原有代码
    
    // 返回视图或数据
    return view('survey.view', compact('survey', 'object', 'date'));
}

3. 方案二:使用模型策略(更优雅,适合中大型项目)

Laravel的模型策略可以把权限逻辑抽离出来,让控制器更简洁,也方便统一管理所有问卷相关的权限规则:

步骤1:生成Survey策略文件

运行Artisan命令创建策略:

php artisan make:policy SurveyPolicy

步骤2:在策略里定义view权限规则

打开app/Policies/SurveyPolicy.php,编写view方法:

public function view(User $user, Survey $survey)
{
    // 校验用户是否在问卷所属团队中
    return $survey->team->users()->where('user_id', $user->id)->exists();
}

步骤3:注册策略

打开app/Providers/AuthServiceProvider.php,在$policies数组里注册策略:

protected $policies = [
    Survey::class => SurveyPolicy::class,
];

步骤4:控制器中使用策略校验

现在你的viewSurvey方法可以简化成这样:

public function viewSurvey($id)
{
    $survey = Survey::findOrFail($id);
    
    // 自动调用SurveyPolicy的view方法校验权限,失败会自动返回403
    $this->authorize('view', $survey);
    
    // 原有业务逻辑
    $object = DB::table('question')->where('survey_id', '=', $id)->get();
    $date = Sur...
    
    return view('survey.view', compact('survey', 'object', 'date'));
}

4. 额外注意事项

  • 确保访问该路由的用户必须登录:给路由加上auth中间件,比如:
    Route::get('/survey/{id}', [YourController::class, 'viewSurvey'])->middleware('auth');
    
  • 如果存在个人问卷(无所属团队),可以扩展校验逻辑,允许问卷创建者直接访问:
    // 在策略或控制器里修改校验逻辑
    return $survey->team->users()->where('user_id', $user->id)->exists() || $survey->creator_id == $user->id;
    
  • 避免N+1查询:可以用with('team')预加载团队关联,减少数据库查询次数:
    $survey = Survey::with('team')->findOrFail($id);
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:41:57