如何使用AWS Cognito Identity JS在React中实现跨域SSO
解决跨域名访问AWS Cognito保护的仪表盘方案
核心问题分析
非托管域名与原网站托管域名分属不同域,localStorage遵循域隔离规则,登录后存在原域的令牌无法被新域读取,导致身份验证失效。
可行实现方案
1. 使用Cognito OAuth授权码流(推荐生产环境)
放弃前端直接存储令牌的方式,改用标准OAuth 2.0授权码流:
- 在Cognito用户池的应用客户端设置中,添加非托管域名作为回调URL和注销URL
- 非托管域名的登录页面引导用户跳转至Cognito授权端点,携带必要参数:
https://<你的用户池域名>/oauth2/authorize?response_type=code&client_id=<你的应用客户端ID>&redirect_uri=<非托管域名回调地址>&scope=openid email profile - 用户完成Cognito登录后,会携带授权码跳转至指定回调地址
- 后端(必须用后端处理,禁止纯前端操作)拿着授权码、客户端ID、客户端密钥(若应用客户端已配置)向Cognito令牌端点请求ID Token、Access Token和Refresh Token
- 后端验证令牌有效性后,通过跨域Cookie(设置
Domain为父域,如两个域名同属.yourdomain.com)或会话机制(将JWT存入HttpOnly Cookie)让仪表盘域读取身份信息 - 仪表盘页面通过读取Cookie中的身份信息,验证通过后展示受保护内容
2. 跨域消息传递(纯前端临时方案,不推荐生产)
若暂时无后端支持,可通过postMessage实现令牌跨域传递:
- 非托管域名登录成功后,打开仪表盘域名的弹窗或新窗口
- 登录页面通过
window.postMessage向仪表盘页面发送令牌,严格指定目标域名 - 仪表盘页面监听
message事件,验证消息来源后接收令牌并存入自身localStorage,再验证令牌有效性 - 示例代码:
此方案令牌在前端暴露,安全风险较高,仅适合测试场景。// 登录页面发送令牌 const dashboardWin = window.open('https://dashboard.yourdomain.com'); setTimeout(() => { dashboardWin.postMessage({ token: '<Cognito合法令牌>' }, 'https://dashboard.yourdomain.com'); }, 1000); // 仪表盘页面接收并验证 window.addEventListener('message', (event) => { if (event.origin !== 'https://login.yourdomain.com') return; if (event.data?.token) { localStorage.setItem('cognitoToken', event.data.token); // 执行令牌验证逻辑后加载仪表盘内容 } });
3. 共享父域Cookie(适合同父域场景)
若两个域名同属一个父域(如login.yourdomain.com和dashboard.yourdomain.com),可通过父域Cookie共享令牌:
- 登录成功后,由后端设置跨域Cookie:
// Node.js示例 res.cookie('cognitoToken', 有效令牌, { httpOnly: true, secure: true, domain: '.yourdomain.com', sameSite: 'None' }); - 仪表盘域名可读取该Cookie,后端验证令牌有效性后允许访问
关键注意事项
- 生产环境必须使用HttpOnly、Secure、SameSite=Strict/None的Cookie存储令牌,防范XSS攻击
- 必须验证令牌的签名、过期时间、受众(Audience)等核心信息,不可直接信任前端传递的令牌
- OAuth授权码流必须由后端处理令牌请求,禁止在前端暴露客户端密钥
内容的提问来源于stack exchange,提问作者Mohammad Altaf Bazaz
相关产品推荐
相关产品推荐

