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

从AWS Cognito获取认证令牌后该如何处理?

AWS Cognito令牌处理、登录状态管理及路由控制实践指导

一、令牌存储的正确姿势

你现在只存在状态变量里的问题很明显:页面一刷新状态就丢了,用户得重新登录,体验拉胯。但直接丢localStorage也有安全风险,分令牌给你说:

  • Access Token/ID Token:可以同时存在「应用状态(比如React Context/Redux)」+「localStorage(或sessionStorage)」。页面加载时先从localStorage读令牌,恢复登录状态。但要注意XSS风险——localStorage是同源可访问的,XSS脚本能直接窃取,所以必须配合XSS防护(比如设置Content-Security-Policy头、过滤用户输入)。如果想降低风险,用sessionStorage代替localStorage,关闭浏览器就自动清除。
  • Refresh Token:绝对不能存localStorage!这玩意儿有效期长(默认30天),被盗了危害极大。纯前端SPA的话,最好存在内存状态里,页面刷新后丢失就让用户重新登录,牺牲一点体验换安全。如果必须持久化,得后端配合把它存到HttpOnly、Secure、SameSite=Strict的Cookie里,前端拿不到,能避免XSS窃取。

二、登录状态维持

  1. 应用启动时(比如入口组件初始化),先检查localStorage里的令牌:
    • 用jwt-decode解析ID Token的exp字段(注意是时间戳,要转成毫秒和当前时间对比),判断是否过期。
    • 令牌有效就加载到应用状态,标记用户已登录;过期或不存在就清空存储,跳登录页。
  2. 平时API调用前,也先校验Access Token的有效期,避免发无效请求。

三、路由访问控制

给需要登录的路由加个守卫组件就行,核心逻辑是「验证令牌有效性」,而不是只看状态变量(状态可能被篡改)。举个React的例子:

import { Navigate } from 'react-router-dom';
import jwtDecode from 'jwt-decode';
import { useAuthContext } from './auth-context';

const PrivateRoute = ({ children }) => {
  const { idToken } = useAuthContext();
  
  // 验证令牌是否存在且未过期
  const isTokenValid = idToken ? jwtDecode(idToken).exp * 1000 > Date.now() : false;

  if (!idToken || !isTokenValid) {
    return <Navigate to="/login" replace />;
  }
  return children;
};

用的时候直接把需要保护的路由包在PrivateRoute里就行。

四、令牌过期与刷新逻辑

别等令牌过期了才处理,提前几分钟(比如5分钟)触发刷新更丝滑:

  1. 解析令牌的exp字段,计算提前刷新的时间点,用定时器触发刷新。
  2. 用Refresh Token调用Cognito的RefreshTokenCommand获取新的Access Token和ID Token,有些场景还会返回新的Refresh Token,记得一起更新。
  3. 刷新成功就更新应用状态和localStorage里的令牌;刷新失败(比如Refresh Token过期),直接清空所有令牌,跳登录页。
    示例代码(AWS SDK v3):
import { CognitoIdentityProviderClient, RefreshTokenCommand } from "@aws-sdk/client-cognito-identity-provider";

const cognitoClient = new CognitoIdentityProviderClient({ region: '你的区域' });

export const refreshAuthTokens = async (refreshToken) => {
  try {
    const command = new RefreshTokenCommand({
      ClientId: '你的Cognito客户端ID',
      RefreshToken: refreshToken,
    });
    const { AuthenticationResult } = await cognitoClient.send(command);
    
    return {
      accessToken: AuthenticationResult.AccessToken,
      idToken: AuthenticationResult.IdToken,
      refreshToken: AuthenticationResult.RefreshToken || refreshToken,
    };
  } catch (err) {
    console.error('令牌刷新失败:', err);
    throw err; // 抛出错误让上层处理登出
  }
};

五、额外要注意的点

  • 不要完全依赖前端的令牌校验:API Gateway本身会验证令牌的有效性,但前端提前校验能减少无效请求。
  • 注销要彻底:用户点击注销时,除了清空localStorage和应用状态,最好调用Cognito的GlobalSignOutCommand让Refresh Token失效,防止被盗用。
  • XSS防护是必须的:只要用了localStorage,就一定要做XSS防护,比如设置CSP头、避免使用eval等危险函数、过滤用户输入内容。

内容的提问来源于stack exchange,提问作者Just Another Programmer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 07:00:56