Laravel控制器向后置中间件传参实现旧密码重置令牌失效问询
问题根因
你现有代码存在两个核心错误:
$next($request)返回的是Illuminate\Http\Response对象,不是你控制器返回的数组,所以直接用数组下标读取肯定会失败- 中间件末尾第二次调用
return $next($request)会重复执行整个请求逻辑,属于严重错误,必须去掉
方案1:解析响应内容(适合需要依赖返回值的场景)
中间件里把响应的JSON内容转成数组读取即可,修改后的中间件代码:
public function handle(Request $request, Closure $next) { // 只调用一次$next,拿到响应对象 $response = $next($request); // 解析响应的JSON内容为数组 $responseData = json_decode($response->getContent(), true); // 先判断参数存在再操作,避免报错 if (!isset($responseData['type'], $responseData['email'])) { // 不是需要处理的请求,直接返回响应 return $response; } $user_email = $responseData['email']; $type = $responseData['type']; // 批量更新旧令牌,不用查询循环,性能更高 if ($type == 'reset') { Password_reset::where('user_email', $user_email) ->where('used', false) ->update(['used' => true]); } else if ($type == 'confirmation') { EmailConfirm::where('user_email', $user_email) ->where('used', false) ->update(['used' => true]); } // 直接返回原来的响应,不要再次调用$next return $response; }
方案2:通过Request实例传参(更优雅,不需要解析响应)
Request对象在整个请求生命周期内是共享的,你可以直接在控制器里把参数存到Request里,中间件直接读取:
控制器修改:
在控制器返回前加一行,把需要的参数存到Request中:
// 其他逻辑不变 $reset_token = $reset_request['reset_token']; $user_email = $request['email']; // 新增:把参数存到Request实例 $request->attributes->add([ 'operate_type' => 'reset', 'operate_email' => $user_email ]); return response(array('message' => 'success', 'email' => $user_email, 'reset_token' => $reset_token, 'type' => 'reset'), status:200);
中间件修改:
public function handle(Request $request, Closure $next) { $response = $next($request); // 直接从Request里读参数 $type = $request->attributes->get('operate_type'); $user_email = $request->attributes->get('operate_email'); if (!$type || !$user_email) { return $response; } // 批量更新逻辑和方案1一致 if ($type == 'reset') { Password_reset::where('user_email', $user_email) ->where('used', false) ->update(['used' => true]); } else if ($type == 'confirmation') { EmailConfirm::where('user_email', $user_email) ->where('used', false) ->update(['used' => true]); } return $response; }
额外优化建议
你原来的循环更新旧令牌的逻辑需要先查询所有记录再逐个保存,IO开销大,直接用update方法做批量更新,一次SQL即可完成操作,性能提升明显。
内容的提问来源于stack exchange,提问作者iiulian8
相关产品推荐
相关产品推荐

