React+Laravel项目Session存储OTP跨接口验证异常问题
OTP验证接口Session跨域及逻辑问题排查与修复
问题描述
我有一个基于React.js和Laravel PHP的项目,包含generate_otp和verify_otp两个接口。generate_otp接口可正常生成OTP并存储到Session中,返回值验证无误,但调用verify_otp接口时,Session变量无值,有时返回500内部服务器错误及'otp'键不存在的错误。后续在前端添加credentials:'include'后,返回值变为固定的错误值(如466782),且每次返回相同值。该问题仅在浏览器中出现,Postman中一切正常。
前端代码
export const generateOTP = async () => { const response = await fetch(`http://localhost:8080/generate_otp`, { method: "GET", headers: { "content-type": "application/json" }, }); }; export const verifyOTP = async (otp) => { const response = await fetch(`http://localhost:8080/verify_otp`, { method: "POST", body: otp, credentials: "include", }); console.log(await response.json()); };
后端代码
$router->post('verify_otp', 'ContactController@verify_otp'); $router->get('generate_otp', 'ContactController@generate_otp'); public function generate_otp(){ session_start(); $otp = random_int(100000, 999999); $_SESSION['otp'] = $otp; return $_SESSION['otp']; } public function verify_otp(Request $request){ session_start(); if($_SESSION['otp'] === $request){ return response()->json(['success'=>1,'message'=>'OTP has been verified']); }else{ return response()->json(['success'=>1,'message'=>'Please enter the correct OTP code']); } }
问题修复步骤
1. 解决跨域Session共享问题
浏览器受同源策略限制,需要前端后端同时配置凭证传递:
- 前端:
generateOTP请求必须添加credentials: 'include',否则生成OTP时的Session Cookie不会被浏览器保存,后续验证请求带的Cookie为空:
export const generateOTP = async () => { const response = await fetch(`http://localhost:8080/generate_otp`, { method: "GET", headers: { "content-type": "application/json" }, credentials: "include", // 新增该行 }); };
- 后端Laravel:修改
config/cors.php开启凭证支持:
return [ 'paths' => ['api/*'], 'allowed_methods' => ['*'], 'allowed_origins' => ['http://localhost:3000'], // 替换为你的React前端地址 'allowed_origins_patterns' => [], 'allowed_headers' => ['*'], 'exposed_headers' => [], 'max_age' => 0, 'supports_credentials' => true, // 必须设为true ];
注意:Laravel框架已自动处理Session初始化,无需手动调用
session_start(),否则会导致Session冲突。
2. 修复OTP验证逻辑错误
后端验证方法存在两个核心问题:直接比较Session值与$request对象、未正确获取前端传入的OTP;前端请求参数格式错误:
- 后端修复:
public function verify_otp(Request $request){ $inputOtp = $request->input('otp'); // 正确获取前端传入的OTP if(isset($_SESSION['otp']) && $_SESSION['otp'] == $inputOtp){ unset($_SESSION['otp']); // 验证成功后销毁OTP,避免重复使用 return response()->json(['success'=>1,'message'=>'OTP已验证通过']); }else{ return response()->json(['success'=>0,'message'=>'请输入正确的OTP验证码']); } }
- 前端修复:传递JSON格式参数并添加请求头:
export const verifyOTP = async (otp) => { const response = await fetch(`http://localhost:8080/verify_otp`, { method: "POST", headers: { "content-type": "application/json" }, // 必须添加该头 body: JSON.stringify({ otp: otp }), // 转为JSON格式传递 credentials: "include", }); console.log(await response.json()); };
3. 确认Laravel Session路由配置
API路由默认无状态,需要为OTP接口添加web中间件启用Session:
Route::group(['middleware' => ['web']], function () { Route::post('verify_otp', 'ContactController@verify_otp'); Route::get('generate_otp', 'ContactController@generate_otp'); });
同时确保.env中Session驱动配置正常:
SESSION_DRIVER=file SESSION_LIFETIME=120
内容的提问来源于stack exchange,提问作者zeshan ahmad
相关产品推荐
相关产品推荐

