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

使用amazon-cognito-identity-js实现Cognito登录与刷新token接口报错如何解决

Amazon Cognito 登录与刷新Token后端实现方案

报错核心原因

你遇到的NotAuthorizedException: Invalid Refresh Token报错,核心问题有两个:

  1. refreshToken方法中硬编码了用户名lacucudi,只有刷新该用户的token时才可能匹配,其他用户、或者用户名大小写不匹配时都会校验失败
  2. 如果你的Cognito用户池应用客户端开启了「生成客户端密钥」,amazon-cognito-identity-js库无法自动处理密钥哈希,也会触发refresh token校验失败

正确实现代码

第一步:抽离公共配置

避免重复初始化用户池实例,敏感配置建议放到环境变量中存储:

import { AuthenticationDetails, CognitoUser, CognitoUserPool, CognitoRefreshToken } from "amazon-cognito-identity-js"

// 配置信息建议从环境变量读取,不要硬编码在业务代码中
const COGNITO_CONFIG = {
  UserPoolId: process.env.COGNITO_USER_POOL_ID || 'eu-north-1_xxxxxx',
  ClientId: process.env.COGNITO_CLIENT_ID || '3al0l3mhcxxxxxqgnp789987'
}
// 全局复用用户池实例
const userPool = new CognitoUserPool(COGNITO_CONFIG)

第二步:登录接口实现

封装为Promise形式,方便后端路由层调用返回响应:

/**
 * 用户名密码登录
 * @param username 用户名
 * @param password 密码
 * @returns token集合
 */
public async loginWithAmazonCognitoIdentity (username: string, password: string): Promise<{
  accessToken: string,
  idToken: string,
  refreshToken: string,
  expireIn: number
}> {
  const authenticationDetails = new AuthenticationDetails({
    Username: username,
    Password: password
  })
  const cognitoUser = new CognitoUser({
    Username: username,
    Pool: userPool
  })

  return new Promise((resolve, reject) => {
    cognitoUser.authenticateUser(authenticationDetails, {
      onSuccess: (result) => {
        resolve({
          accessToken: result.getAccessToken().getJwtToken(),
          idToken: result.getIdToken().getJwtToken(),
          refreshToken: result.getRefreshToken().getToken(),
          expireIn: result.getAccessToken().getExpiration()
        })
      },
      onFailure: (err) => {
        reject(err)
      }
    })
  })
}

第三步:刷新Token接口实现

必须传入用户名和refreshToken两个参数,不能硬编码用户名:

/**
 * 刷新Access Token
 * @param username 对应用户的用户名(需和登录时传入的完全一致,包含大小写)
 * @param refreshToken 登录时获取的refresh token
 * @returns 新的token集合
 */
public async refreshToken(username: string, refreshToken: string): Promise<{
  accessToken: string,
  idToken: string,
  refreshToken: string,
  expireIn: number
}> {
  const cognitoUser = new CognitoUser({
    Username: username,
    Pool: userPool
  })
  const refreshTokenInstance = new CognitoRefreshToken({ RefreshToken: refreshToken })

  return new Promise((resolve, reject) => {
    cognitoUser.refreshSession(refreshTokenInstance, (err, session) => {
      if (err) return reject(err)
      resolve({
        accessToken: session.getAccessToken().getJwtToken(),
        idToken: session.getIdToken().getJwtToken(),
        refreshToken: session.getRefreshToken().getToken(),
        expireIn: session.getAccessToken().getExpiration()
      })
    })
  })
}

注意事项

  • 创建Cognito用户池应用客户端时不要勾选「生成客户端密钥」,amazon-cognito-identity-js仅支持无密钥的客户端场景
  • 刷新token时传入的用户名必须和登录时的用户名完全一致,包含大小写
  • 用户被禁用、修改密码、refresh token超过有效期时,都会触发Invalid Refresh Token报错,可在Cognito用户池控制台的「应用客户端设置」中调整refresh token的有效期,最长支持10年
  • 若开启了用户池的设备跟踪功能,需要在登录时保存设备Key,刷新时传入设备信息,否则也会校验失败

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 06:45:03