Laravel+React集成Microsoft Graph用户认证及CORS问题解决
Laravel 9 + React 18 联动Microsoft Graph认证问题解决方案
一、修复CORS重定向错误
问题根因
React通过Fetch/Ajax调用Laravel的/api/login接口时,接口直接返回302重定向到微软授权地址,浏览器跨域策略会阻止这类跨域重定向到第三方域名的行为。
解决方案
- 修改Laravel登录接口逻辑:不再直接重定向,返回授权URL字符串让前端主动跳转
// app/Http/Controllers/Auth/MicrosoftAuthController.php public function redirect() { $provider = Socialite::driver('microsoft'); $authUrl = $provider->redirect()->getTargetUrl(); return response()->json(['auth_url' => $authUrl]); }
- 调整React登录组件逻辑:调用接口后拿到URL,通过
window.location.href主动跳转
// src/components/Login.js const handleLogin = async () => { try { const response = await fetch('http://127.0.0.1:8000/api/login', { method: 'GET', credentials: 'include' }); const data = await response.json(); window.location.href = data.auth_url; } catch (error) { console.error('登录请求失败:', error); } };
- 修正Laravel CORS配置:更新
config/cors.php
return [ 'paths' => ['api/*', 'sanctum/csrf-cookie'], 'allowed_methods' => ['*'], 'allowed_origins' => ['http://localhost:3000'], // React项目地址 'allowed_origins_patterns' => [], 'allowed_headers' => ['*'], 'exposed_headers' => [], 'max_age' => 0, 'supports_credentials' => true, ];
二、回调逻辑的触发与衔接
完整流程梳理
- 用户在React页点击登录 → 调用Laravel接口获取微软授权URL → 跳转微软登录页
- 用户完成微软认证 → 微软回调到Laravel预设的回调接口
- Laravel处理回调:获取token、调用Microsoft Graph拉取用户信息、创建/更新本地用户、生成API凭证
- Laravel重定向回React页面,携带API凭证
- React获取凭证并存储,完成登录状态初始化
具体实现步骤
配置Azure回调URL:在Azure Portal应用注册中,设置重定向URI为
http://127.0.0.1:8000/api/callbackLaravel回调接口实现:处理授权码并生成API Token
// app/Http/Controllers/Auth/MicrosoftAuthController.php use Laravel\Sanctum\PersonalAccessToken; public function callback() { $user = Socialite::driver('microsoft')->user(); $localUser = User::updateOrCreate( ['email' => $user->getEmail()], ['name' => $user->getName(), 'microsoft_id' => $user->getId()] ); $token = $localUser->createToken('microsoft-auth')->plainTextToken; // 重定向回React页面并携带token return redirect()->to("http://localhost:3000?token={$token}"); // 更安全的方式:设置HttpOnly Cookie // return redirect()->to('http://localhost:3000')->withCookie(cookie('api_token', $token, 60*24*7)); }
- React端处理回调参数:在首页或路由守卫中获取token、存储并验证
// src/App.js import { useEffect, useState } from 'react'; function App() { const [user, setUser] = useState(null); useEffect(() => { const urlParams = new URLSearchParams(window.location.search); const token = urlParams.get('token'); if (token) { localStorage.setItem('api_token', token); window.history.replaceState({}, document.title, window.location.pathname); fetchUser(token); } else { const savedToken = localStorage.getItem('api_token'); savedToken && fetchUser(savedToken); } }, []); const fetchUser = async (token) => { try { const response = await fetch('http://127.0.0.1:8000/api/user', { headers: { 'Authorization': `Bearer ${token}` } }); const userData = await response.json(); setUser(userData); } catch (error) { console.error('获取用户信息失败:', error); localStorage.removeItem('api_token'); } }; return ( <div className="App"> {user ? ( <div>欢迎回来,{user.name}</div> ) : ( <button onClick={() => window.location.href = 'http://127.0.0.1:8000/api/login'}> 微软登录 </button> )} </div> ); } export default App;
- Laravel提供用户信息接口:
// routes/api.php Route::middleware('auth:sanctum')->get('/user', function (Request $request) { return $request->user(); });
内容的提问来源于stack exchange,提问作者Elodie
相关产品推荐
相关产品推荐

