【问题标题】:Losing session data after POST from third party website从第三方网站 POST 后丢失会话数据
【发布时间】:2021-08-13 22:57:14
【问题描述】:

我有一个 Laravel 网站,该网站重定向到支付提供商(外部第三方网站)。当用户完成付款后,他们会通过 POST 请求重定向回我的网站。

我遇到的问题是用户返回确认页面时会话丢失。

我想知道这是否是 PHP 的一般行为,但它似乎是 Laravel 特有的。

我检查了我的 sessions.php 配置文件,可以确认以下设置为 'expire_on_close' => false,

我在下面创建了一个非常基本的问题示例

我的网站(预售)

控制器

public function redirect()
{
    $user = Auth::user();
    dd($user); // returns User model;
    redirect()->away('http://www.example.com');

}

支付提供商网站

请注意,请求是通过浏览器中的应用程序发送的,而不是回调。也没有按钮。我只是想将 POST 演示回 Laravel 站点。

<html>
<head></head>
<body>

    <form method="POST" action="http://www.example.com/payment/confirmation">
        <input type="submit">
    </form>

</body>
</html>

我的网站(售后)

路线

Route::post('/payment/confirmation', 'Payment\PaymentController@confirmation');

控制器

public function confirmation()
{

    $user =  Auth::user();
    dd($user); // Returns null

}

我已将路径添加到 VerifyCsrfToken 中间件的异常数组。 Laravel 中是否有任何东西会破坏通过外部网站发布的会话?我确定我遗漏了一些明显的东西。谢谢

【问题讨论】:

  • 请尝试使用 Link Tracer 扩展跟踪生命周期中的所有请求,并发布所有重定向的屏幕截图。 chrome.google.com/webstore/detail/link-redirect-trace/…
  • 这可能是由于在设置会话 cookie 时使用了不正确的 SameSite 值。
  • 这确实是由 config/session.php 中的same_site 设置引起的。将此设置为 null 可以解决问题。

标签: php laravel session post


【解决方案1】:

在我的测试中,似乎会话实际上并没有被破坏。但是,在接收到外部 POST 请求时不会加载,如果允许返回主站点触发新的会话保存,会话将被销毁。通过发送header() 重定向并在保存新会话之前终止进程,似乎可以恢复现有会话。

好吧,也许有点恶心?

Route::match(['get','post'],'/payment/confirmation','Payment\PaymentController@confirmation');
public function confirmation(Request $request)
{
    // assert cookie or reload current URL
    if (! $request->hasHeader('Cookie')) {
        header('Location: '.url()->current());
        exit;
    }

    $user = Auth::user();
    dd($user); // user exists!
}

我不会说这是一个很好的解决方案。确实感觉有点hackish。可能需要进行一些额外的测试。但乍一看,它似乎确实有效——至少在我这边。也许它可以让我们对幕后实际发生的事情有一些额外的了解。

另外,我不确定您是否要向 GET 请求公开付款确认页面。

但这是一个有趣的兔子洞。

【讨论】:

  • 感谢您的回答。我能够通过更改 config/session.php 中的 same_site 设置来解决问题
  • 有趣。这对我来说是一个新的。我得去看看。谢谢。
【解决方案2】:

我可以通过在 config/session.php 中将 'same_site' =&gt; 'lax', 更改为 'same_site' =&gt; null, 来解决此问题。这似乎是 Laravel 7+ 中的新设置。

如果没有进一步阅读,我不确定此更改是否会导致任何安全隐患,但目前,这可以解决问题。以某种方式将某些域列入白名单将是一个不错的功能。

【讨论】:

    【解决方案3】:

    设置 'same_site' => null 可能无法再次按预期工作,因为与 Cookie SameSite 属性相关的标准最近更改了https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite

    现在新的默认值为 Lax,因此如果您将 same_site 设置为 null,浏览器将采用默认的 Lax,这不是您需要的策略。

    您需要明确设置 'same_site' => "none",same_site 的值为 none 要求您的连接是安全的,因此,设置 'secure' => true。

    'same_site' => "none"
    'secure' => true
    

    【讨论】:

      猜你喜欢
      • 2020-11-11
      • 2015-08-20
      • 2018-11-24
      • 2020-07-14
      • 1970-01-01
      • 2018-11-25
      • 1970-01-01
      • 2017-04-05
      • 1970-01-01
      相关资源
      最近更新 更多