Cognito:如何检测用户已有会话并实现单设备登录(基于Amplify)
实现方案:多浏览器登录时踢除旧Cognito会话
这个需求完全可以实现,核心思路是利用Cognito的用户会话管理能力,结合Amplify提供的API主动撤销旧会话并创建新会话。
关键原理
Cognito会为每个登录会话生成唯一的refresh token和access token,当用户在新设备/浏览器登录时,我们可以主动撤销该用户名下所有旧的refresh token,强制旧会话失效,同时保留新登录生成的会话。
具体实现步骤
1. 登录时触发旧会话撤销逻辑
在用户通过Amplify完成新登录后,调用Cognito的相关接口清理旧会话:
- 先通过Amplify获取当前用户的新会话
refresh token - 获取该用户所有登录事件,筛选出除当前新token外的旧refresh token
- 对每个旧token调用撤销接口,使其失效
2. 代码示例(基于Amplify)
import { Auth } from 'aws-amplify'; // 新登录完成后执行旧会话清理 async function revokeOldSessions() { const currentUser = await Auth.currentAuthenticatedUser(); const currentRefreshToken = currentUser.signInUserSession.refreshToken.token; // 获取用户所有认证事件 const authEvents = await Auth.userAttributes(currentUser, { userAuthEvents: true }); // 筛选出旧的refresh token(排除当前新生成的) const oldRefreshTokens = authEvents .filter(event => event.eventType === 'RefreshTokenIssued' && event.refreshToken !== currentRefreshToken) .map(event => event.refreshToken); // 批量撤销旧token for (const token of oldRefreshTokens) { try { await Auth.revokeToken(token); } catch (err) { console.error('撤销旧会话失败:', err); } } } // 在登录成功回调中触发清理逻辑 Auth.signIn(username, password) .then(user => { console.log('登录成功'); return revokeOldSessions(); }) .catch(err => console.log('登录错误:', err));
3. 简化配置:限制并发会话数
你也可以直接在Cognito用户池的应用客户端设置中,开启「设置用户并发会话数限制」并设为1。这样用户新登录时,Cognito会自动撤销最旧的会话,无需手动编写撤销逻辑,大幅简化实现流程。
注意事项
- 撤销refresh token后,旧会话的access token在过期前仍能使用,若需立即失效access token,需结合Cognito的令牌撤销列表或自定义后端验证逻辑
- Amplify的
revokeToken方法需要确保应用客户端拥有cognito-idp:RevokeToken的IAM权限
内容的提问来源于stack exchange,提问作者Crits
相关产品推荐
相关产品推荐

