MercadoPago支付完成跳转回站后PHP session丢失、原有cookie无法读取
核心原因
- 浏览器SameSite Cookie限制:未显式配置SameSite属性的Cookie默认使用Lax策略,MercadoPago属于第三方跨站跳转,跳转请求不会携带原站点Cookie,导致服务端无法读取原有PHPSESSID与user_token,生成新的Session ID
- Cookie配置缺失:原有代码设置Cookie时未指定路径、域、Secure、SameSite属性,跨站场景下无法被正常携带
- 代码存在SQL注入风险:直接拼接用户可控参数到SQL语句,存在数据泄露、被篡改风险
修复后的完整代码
<?php // 配置Session Cookie参数,必须放在session_start之前 session_set_cookie_params([ 'lifetime' => 2 * 24 * 60 * 60, 'path' => '/', 'domain' => '你的站点域名,例如xxx.com', // 统一使用根域名,避免多域名下Cookie不一致 'secure' => true, // 仅HTTPS请求携带Cookie 'httponly' => true, // 禁止JS读取Cookie,降低XSS风险 'samesite' => 'None' // 允许跨站跳转携带Cookie ]); session_start(); include("db-connection.php"); if(isset($_SESSION["id_alumno"])) { $sid = session_id(); if(!isset($_COOKIE["user_token"])){ // PHP 7.3+ 支持直接传samesite参数 setcookie( "user_token", $sid, time() + 2 * 24 * 60 * 60, '/', '你的站点域名,例如xxx.com', true, true, ['samesite' => 'None'] ); // PHP <7.3版本使用header方式设置Cookie: // header("Set-Cookie: user_token=$sid; Expires=".gmdate('D, d M Y H:i:s T', time()+2*24*60*60)."; Path=/; Domain=你的站点域名; Secure; HttpOnly; SameSite=None"); // 使用预处理语句避免SQL注入 $id_alumno = $_SESSION["id_alumno"]; $stmt = mysqli_prepare($link, "UPDATE `alumno` SET `login_token` = ?, `login_creado` = NOW() WHERE `alumno`.`id` = ?"); mysqli_stmt_bind_param($stmt, "si", $sid, $id_alumno); mysqli_stmt_execute($stmt); } } else { $cookie_value = $_COOKIE["user_token"] ?? ''; if(!empty($cookie_value)){ // 使用预处理语句查询 $stmt = mysqli_prepare($link, "SELECT * FROM alumno WHERE login_token = ? AND login_token != 'no'"); mysqli_stmt_bind_param($stmt, "s", $cookie_value); mysqli_stmt_execute($stmt); $res = mysqli_stmt_get_result($stmt); if($reg = mysqli_fetch_array($res)) { // 匹配到用户信息,手动写入Session实现自动登录 $_SESSION["id_alumno"] = $reg['id']; } } } ?>
注意:SameSite=None配置仅在HTTPS环境下生效,本地HTTP测试时可临时调整为SameSite=Lax验证逻辑,上线后改回None即可。
可选兼容方案
如果暂时无法调整Cookie配置,可在跳转到MercadoPago前,将当前用户的login_token存入传给支付平台的回调参数中,用户跳转回站点时从GET/POST参数中读取该token,再匹配数据库实现自动登录,该方案不受Cookie跨站规则限制。
内容的提问来源于stack exchange,提问作者Sebastian Ocaño
相关产品推荐
相关产品推荐

