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

React JS环境下如何在客户端安全存储用户登录凭证?

在React中安全存储登录凭证的最佳实践

首先明确核心原则:绝对不要在客户端存储用户的密码或明文凭证,要依赖后端提供的Token认证体系(比如JWT的Access Token + Refresh Token分离方案),以下是具体的安全存储策略:

1. 用HttpOnly Cookie存储Refresh Token

这是最安全的长期登录凭证存储方式:

  • 后端在用户登录成功后,将Refresh Token存入HttpOnly、Secure、SameSite属性的Cookie中返回给前端。HttpOnly标记会禁止前端JS读取该Cookie,从根源上避免XSS攻击窃取Token;Secure确保Cookie仅通过HTTPS传输;SameSite=Strict/Lax能有效防范CSRF攻击。
  • 前端无需手动操作这个Cookie,后续调用刷新Token的接口时,浏览器会自动将Cookie携带到请求中。

2. Access Token存入内存(React状态/全局Context)

Access Token是短期有效的接口认证凭证,适合存在内存中:

  • 登录成功后,后端返回Access Token,前端将其存入useState或全局Context(比如AuthContext)里,每次发起API请求时,在请求头中携带Authorization: Bearer ${accessToken}。
  • 页面刷新后内存中的Token会消失,此时需要调用后端的刷新Token接口,用Cookie中的Refresh Token换取新的Access Token,重新存入内存,实现自动登录。

3. 绝对避免使用localStorage/sessionStorage

这两种存储方式是前端JS可直接读取的,一旦页面遭遇XSS攻击,攻击者能轻松窃取存储的Token,进而冒充用户执行敏感操作,完全不符合安全要求。


React中的具体实现示例

1. 登录组件处理

import { useState, useContext } from 'react';
import AuthContext from './AuthContext';

const Login = () => {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const { setAccessToken } = useContext(AuthContext);

  const handleLogin = async (e) => {
    e.preventDefault();
    try {
      const res = await fetch('/api/login', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ email, password })
      });
      const data = await res.json();
      // 将Access Token存入全局上下文
      setAccessToken(data.accessToken);
    } catch (err) {
      console.error('登录失败:', err);
    }
  };

  return (
    <form onSubmit={handleLogin}>
      <input
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        placeholder="邮箱"
        required
      />
      <input
        type="password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
        placeholder="密码"
        required
      />
      <button type="submit">登录</button>
    </form>
  );
};

export default Login;

2. App初始化时自动刷新Token

import { useEffect, useState } from 'react';
import AuthContext from './AuthContext';
import { Routes, Route } from 'react-router-dom';
import Login from './Login';
import Dashboard from './Dashboard';

function App() {
  const [accessToken, setAccessToken] = useState(null);

  useEffect(() => {
    // 页面加载后尝试用Refresh Token获取新的Access Token
    const refreshAccessToken = async () => {
      try {
        const res = await fetch('/api/refresh-token', {
          method: 'POST',
          // 允许携带Cookie
          credentials: 'include'
        });
        if (res.ok) {
          const data = await res.json();
          setAccessToken(data.accessToken);
        }
      } catch (err) {
        console.error('Token刷新失败:', err);
      }
    };
    refreshAccessToken();
  }, []);

  return (
    <AuthContext.Provider value={{ accessToken, setAccessToken }}>
      <Routes>
        {accessToken ? (
          <Route path="/" element={<Dashboard />} />
        ) : (
          <Route path="/" element={<Login />} />
        )}
      </Routes>
    </AuthContext.Provider>
  );
}

export default App;

3. 发起带认证的API请求

import { useContext, useState, useEffect } from 'react';
import AuthContext from './AuthContext';

const Dashboard = () => {
  const { accessToken } = useContext(AuthContext);
  const [userData, setUserData] = useState(null);

  useEffect(() => {
    const fetchUserData = async () => {
      try {
        const res = await fetch('/api/user/profile', {
          headers: {
            Authorization: `Bearer ${accessToken}`
          }
        });
        const data = await res.json();
        setUserData(data);
      } catch (err) {
        console.error('获取用户数据失败:', err);
      }
    };
    fetchUserData();
  }, [accessToken]);

  return (
    <div>
      {userData ? <h1>欢迎回来,{userData.name}</h1> : <p>加载中...</p>}
    </div>
  );
};

export default Dashboard;

额外安全补充

  • 缩短Access Token的有效期(建议15-30分钟),Refresh Token可以设置较长有效期,但要支持用户主动注销时立即失效,并且后端要定期清理过期的Refresh Token。
  • 后端必须严格验证Token的签名、有效期和颁发者,防止伪造Token。
  • 配置CORS策略,仅允许你的前端域名访问后端API,避免跨域恶意请求。
  • 对于修改密码、资金操作等敏感接口,必须要求二次验证(比如短信验证码、指纹验证),不要完全依赖自动登录的凭证。

内容的提问来源于stack exchange,提问作者Inaara Kalani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 14:39:13