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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:49:14