Laravel中排除VerifyCsrfToken的WebMoney回调路由内用户登出,无法获取用户求助
解决Laravel中WebMoney回调无法获取当前用户的问题
这个问题的核心原因很明确:WebMoney的POST回调是服务器到服务器的请求,不是用户在浏览器中发起的请求,所以这个请求不会携带用户浏览器里的Session Cookie。Laravel是通过Session来识别当前登录用户的,没有Session标识,自然就认为用户处于登出状态。
下面是具体的解决方案:
1. 发起支付时传递用户标识
在你生成WebMoney支付请求的环节,需要把当前登录用户的唯一标识(比如用户ID)传递给WebMoney网关。通常可以利用WebMoney支持的自定义参数字段(比如custom、description或者专门的额外参数,具体参考WebMoney的集成文档)。
示例代码:
// 生成支付请求时的代码片段 $paymentParams = [ 'amount' => 99.99, 'currency' => 'WMR', 'custom' => auth()->id(), // 将当前登录用户ID存入自定义字段 // 其他WebMoney要求的必填参数... ];
2. 在回调路由中接收并关联用户
当WebMoney网关发起回调请求时,你可以从请求参数中取出之前传递的用户ID,然后通过这个ID直接查找用户,甚至可以手动登录该用户(如果后续逻辑需要使用auth()辅助函数)。
示例回调路由代码:
Route::post('/webmoney/callback', function(\Illuminate\Http\Request $request) { // 第一步:务必验证WebMoney回调的合法性! // 这一步非常关键,要按照WebMoney文档的要求校验签名,防止恶意伪造请求 // 比如校验签名哈希、请求来源等 // 取出之前传递的用户ID $userId = $request->input('custom'); // 查找对应的用户 $user = \App\Models\User::find($userId); if ($user) { // 如果后续逻辑需要使用auth()获取用户,可以手动登录该用户 auth()->loginUsingId($userId); // 这里执行你的业务逻辑,比如更新订单状态、记录支付日志等 // 例如:$user->orders()->where('order_no', $request->input('order_no'))->update(['status' => 'paid']); } else { // 处理用户不存在的异常情况,比如记录警告日志 \Illuminate\Support\Facades\Log::warning('WebMoney回调中无法找到用户,用户ID:'.$userId); } // 返回WebMoney要求的响应(通常是"OK"或者指定格式的响应) return response('OK', 200); });
关键注意事项
- 必须验证回调合法性:永远不要直接信任回调中的任何参数,一定要按照WebMoney官方文档的要求对请求进行签名校验,避免被恶意攻击。
- 不要依赖Session:服务器间请求没有Session上下文,所以任何依赖
auth()->user()的逻辑都要改为通过用户ID直接查找用户。 - 手动登录的安全性:如果在回调中手动登录用户,要确保后续的业务逻辑不会产生安全风险,比如不要在回调中执行需要用户交互的操作,只处理支付相关的状态更新。
内容的提问来源于stack exchange,提问作者Mehdi Meshkatian
相关产品推荐
相关产品推荐

