You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React 18+JS:接收API响应JWT并存储到Cookie的问题排查

解决React登录后Cookie无法存储的问题

一、先排查响应体解析逻辑

你提到API返回无括号的JSON(即直接返回JWT字符串,而非包含x-auth-token字段的JSON对象),但现有代码尝试从jsonResponse["x-auth-token"]取值,这会导致authToken为undefined,根本不会执行Cookie存储逻辑。

修复方案:

根据API返回格式调整解析方式:

  • 如果API直接返回纯JWT字符串:
    // 替换原解析逻辑
    const authToken = await response.text();
    
  • 如果API实际返回包含x-auth-token的JSON对象(如{"x-auth-token": "xxx.yyy.zzz"}):
    保持原response.json()解析,但需确认接口返回结构与代码匹配。

二、补充Cookie的必要属性

即使token获取正确,跨域场景下(前端与API域名不同,比如前端在localhost:3000、API在https://myapi.com),直接设置document.cookie会因浏览器同源策略失效,需补充关键属性:

修改Cookie存储代码:

document.cookie = `x-auth-token=${authToken}; path=/; secure; SameSite=None`;
  • secure:API为HTTPS时必须添加,仅允许Cookie通过HTTPS传输存储
  • SameSite=None:允许跨域请求携带Cookie,需与secure搭配使用
  • path=/:确保Cookie在全站范围内可用

如果前端与API同主域名,可额外添加domain=.myapi.com实现子域名共享Cookie。

三、配置跨域请求的Credentials

跨域场景下,fetch请求需显式开启credentials: 'include',否则浏览器会阻止Cookie的存储与发送:

修改fetch请求:

const response = await fetch("https://myapi.com/api/auth", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  credentials: 'include', // 新增此行
  body: JSON.stringify({ email, password }),
});

同时后端需配合配置CORS头:

  • Access-Control-Allow-Origin:设置为前端具体域名(如http://localhost:3000),不能用*
  • Access-Control-Allow-Credentials: true

四、完整修复后的代码示例

import React, { useState } from "react";

const LoginForm: React.FC = () => {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [token, setToken] = useState<string | null>(null);

  const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();

    try {
      const response = await fetch("https://myapi.com/api/auth", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        credentials: 'include',
        body: JSON.stringify({ email, password }),
      });

      if (!response.ok) {
        throw new Error("Failed to login");
      }

      // 根据API返回格式选择解析方式
      const authToken = await response.text();
      // 若API返回JSON对象则启用下方代码:
      // const jsonResponse = await response.json();
      // const authToken = jsonResponse["x-auth-token"];

      if (authToken) {
        document.cookie = `x-auth-token=${authToken}; path=/; secure; SameSite=None`;
        setToken(authToken);
        console.log("Token:", authToken);
      } else {
        throw new Error("Token not found in response");
      }
    } catch (error) {
      console.error("Login Error:", (error as Error).message);
    }
  };

  return (
    <div>
      <h2>Login Form</h2>
      {token ? (
        <p>Logged in! Token: {token}</p>
      ) : (
        <form onSubmit={handleSubmit}>
          <div>
            <label htmlFor="email">Email:</label>
            <input
              type="email"
              id="email"
              name="email"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
              required
            />
          </div>
          <div>
            <label htmlFor="password">Password:</label>
            <input
              type="password"
              id="password"
              name="password"
              value={password}
              onChange={(e) => setPassword(e.target.value)}
              required
            />
          </div>
          <button type="submit">Login</button>
        </form>
      )}
    </div>
  );
};

export default LoginForm;

五、验证步骤

  1. 登录后打开开发者工具Application面板,查看Cookies列表确认x-auth-token是否存在
  2. 若仍无Cookie,检查控制台是否有Cookie相关错误(如SameSite属性不匹配、域名不一致等)
  3. 确认后端CORS配置是否符合要求

内容的提问来源于stack exchange,提问作者Hunter C

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 03:52:06