如何在Laravel通知查询结果中排除password与remember_token列?
如何在Laravel查询结果中排除指定敏感列
问题背景
你想要在查询输出中排除password和remember_token列,目前使用Query Builder编写的控制器代码返回结果包含了这两个敏感字段。你的代码如下:
public function notifications(){ $notifs=DB::table('notifications') ->leftJoin('users','users.id','notifications.user_logged') ->where('user_hero',Auth::user()->id) ->where('status',1) ->orderBy('notifications.created_at','disc') ->get(); dd($notifs); }
解决方案
这里有几种可行的方法,你可以根据自己的场景选择:
1. 明确指定需要返回的字段(最稳妥)
既然你不想要某些字段,最直接的方式就是只选择你需要的字段。这样能精准控制返回数据,避免意外泄露敏感信息:
public function notifications(){ $notifs=DB::table('notifications') ->leftJoin('users','users.id','notifications.user_logged') // 选择notifications表的所有字段,加上users表中你需要的字段(排除password和remember_token) ->select( 'notifications.*', 'users.id', 'users.name', 'users.email' // 这里继续添加你需要的其他users表字段 ) ->where('user_hero',Auth::user()->id) ->where('status',1) ->orderBy('notifications.created_at','desc') // 注意:原代码里的'disc'是笔误,应该是'desc' ->get(); dd($notifs); }
2. 使用原生SQL语法排除字段(适合字段较多的场景)
如果users表的字段很多,不想逐个罗列,可以用原生SQL的方式排除指定字段,但要注意语法兼容性:
- 如果你用的是PostgreSQL,可以用
EXCEPT:
public function notifications(){ $notifs=DB::table('notifications') ->leftJoin('users','users.id','notifications.user_logged') ->select('notifications.*') ->selectRaw('users.* EXCEPT (password, remember_token)') ->where('user_hero',Auth::user()->id) ->where('status',1) ->orderBy('notifications.created_at','desc') ->get(); dd($notifs); }
- 如果你用的是MySQL,因为它不支持
EXCEPT,可以直接在SELECT中列出所有需要的字段并排除那两个,或者使用下面的Eloquent模型方法。
3. 使用Eloquent模型的隐藏属性(Laravel最佳实践)
如果你的Notification和User都有对应的Eloquent模型,推荐在User模型中设置$hidden属性,这样所有返回的User实例都会自动隐藏这些敏感字段:
// app/Models/User.php class User extends Model { // 自动隐藏这些敏感字段 protected $hidden = ['password', 'remember_token']; }
然后用Eloquent关联来查询,代码会更简洁:
public function notifications(){ $notifs = Notification::with('userLogged') // 假设你在Notification模型中定义了userLogged关联 ->where('user_hero', Auth::user()->id) ->where('status', 1) ->orderBy('created_at', 'desc') ->get(); dd($notifs); }
如果想要双重保险,还可以在关联查询时额外指定要选择的字段:
$notifs = Notification::with(['userLogged' => function($query) { $query->select('id', 'name', 'email'); }]) ->where('user_hero', Auth::user()->id) ->where('status', 1) ->orderBy('created_at', 'desc') ->get();
最后提醒:原代码中的orderBy('notifications.created_at','disc')里的disc是拼写错误,正确的降序参数是desc,我在所有示例中都已经修正了这个问题。
内容的提问来源于stack exchange,提问作者Biswas Sampad
相关产品推荐
相关产品推荐

