GSI脚本POST重定向后端后,如何携带Token跳转至React前端?
问题根源
你用GSI的data-login_uri是表单POST提交模式,浏览器会直接渲染后端返回的响应内容——所以返回Ok(token)会停在API路径,用Redirect又没法直接附加Token对象。下面给三个实用解决方案,按推荐程度排序:
方案1:前端接管谷歌登录流程(推荐,符合前后端分离架构)
放弃data-login_uri,改用前端回调处理谷歌登录结果,再通过AJAX调用后端API验证,最后自行跳转并存储Token。
前端代码调整(login.jsx)
修改GSI脚本配置,移除data-login_uri,添加data-callback指定前端回调函数:
<div id="g_id_onload" data-client_id="XXX" data-context="signin" data-ux_mode="popup" data-auto_prompt="false" data-callback="handleGoogleLogin"> <!-- 添加回调配置 --> </div> <div className="g_id_signin" data-type="standard" data-shape="rectangular" data-theme="outline" data-text="signin_with" data-size="large" data-logo_alignment="left"> </div> <!-- 在login.jsx中定义回调函数 --> <script> window.handleGoogleLogin = async (response) => { try { // 把谷歌返回的credential传给后端验证 const formData = new FormData(); formData.append('credential', response.credential); const res = await fetch('https://localhost:44462/api/login', { method: 'POST', body: formData }); if (!res.ok) throw new Error('验证失败'); const token = await res.json(); // 存储Token(比如localStorage或Cookie) localStorage.setItem('authToken', token); // 跳转到前端目标页面 window.location.href = '/login'; } catch (err) { console.error('登录出错:', err); // 这里可以添加前端错误提示UI } }; </script>
后端代码调整
保持现有验证逻辑,直接返回Token即可(因为是AJAX请求,前端能拿到响应):
[ApiController] [Route("api/")] public class GoogleAuthController : Controller { private readonly IConfiguration _config; // 注入配置 public GoogleAuthController(IConfiguration config) { _config = config; } [HttpPost] [Route("login")] public async Task<IActionResult> ReturnFromApi() { var tokenid = HttpContext.Request.Form["credential"]; GoogleJsonWebSignature.Payload payload = await GoogleJsonWebSignature.ValidateAsync(tokenid); if (!payload.Audience.Equals(_config["ClientId"])) return BadRequest("客户端ID不匹配"); // 生成你的用户Token逻辑... var token = "生成的JWT或自定义Token"; return Ok(token); } }
方案2:后端返回自动跳转页面,携带Token
如果不想改前端GSI配置,后端可以返回一个包含跳转脚本的HTML页面,把Token存入前端存储后再跳转。
后端代码修改
替换return Ok(token)为以下代码:
public async Task<IActionResult> ReturnFromApi() { // ... 原有验证逻辑 ... var token = "生成的用户Token"; // 返回自动跳转的HTML页面,将Token存入localStorage var redirectHtml = $@" <!DOCTYPE html> <html> <head> <meta charset='UTF-8'> <script> try {{ localStorage.setItem('authToken', '{token}'); window.location.href = '/login'; }} catch (err) {{ alert('登录失败,请重试'); window.location.href = '/login'; }} </script> </head> <body></body> </html>"; return Content(redirectHtml, "text/html"); }
注意:如果Token包含特殊字符,需要先做HTML编码,避免脚本语法错误。
方案3:用HttpOnly Cookie存储Token(同域场景适用)
如果前后端是同域名(比如用反向代理统一域名,或主域名相同),可以把Token存入HttpOnly Cookie,再跳转前端,后续请求自动携带Cookie。
后端代码修改
public async Task<IActionResult> ReturnFromApi() { // ... 原有验证逻辑 ... var token = "生成的用户Token"; // 设置HttpOnly Cookie(安全防XSS) Response.Cookies.Append("AuthToken", token, new CookieOptions { HttpOnly = true, Secure = true, // HTTPS环境下启用 SameSite = SameSiteMode.Strict, // 防CSRF攻击 Expires = DateTimeOffset.UtcNow.AddDays(7), // 有效期 Path = "/" // 全站可用 }); return Redirect("/login"); }
前端后续发起API请求时,浏览器会自动携带这个Cookie,后端通过Request.Cookies["AuthToken"]获取并验证即可。
内容的提问来源于stack exchange,提问作者Sirius
相关产品推荐
相关产品推荐

