基于Amazon Cognito的移动端至Web端二维码跨端登录实现问题
基于Amazon Cognito + Amplify的二维码跨端登录解决方案
方案一:使用Amplify Auth.federatedSignIn 直接复用移动端Cognito令牌
移动端登录后拿到的Cognito用户池access token,可通过联合登录机制在Web端完成认证:
- 验证令牌有效性:Web端接收移动端传来的access token后,通过Cognito的
VerifyTokenAPI或JWT库(如jsonwebtoken)解析并验证令牌的签名、过期时间等。 - 调用联合登录方法:验证通过后,调用Amplify的
Auth.federatedSignIn,指定Cognito为提供商并传入令牌:
import { Auth } from 'aws-amplify'; async function loginWithMobileToken(mobileAccessToken) { try { await Auth.federatedSignIn({ provider: 'COGNITO', token: mobileAccessToken, }); const user = await Auth.currentAuthenticatedUser(); console.log('登录成功', user); } catch (err) { console.error('登录失败', err); } }
注意:需确保Amplify配置中用户池与身份池已正确关联,且身份池允许Cognito用户池作为身份提供商。
方案二:通过Lambda触发器实现自定义认证流程
如果需要更灵活的控制,可借助Cognito的自定义认证触发器,结合Pusher完成跨端认证:
- 配置Cognito自定义认证:在用户池设置中启用「自定义认证」,添加
Define Auth Challenge和Verify Auth Challenge Response两个Lambda触发器。 - Web端发起认证请求:调用
Auth.signIn时传入移动端用户的sub作为用户名,触发自定义挑战:
async function initiateCustomLogin(userSub) { try { const challengeResponse = await Auth.signIn(userSub); // 触发Lambda的自定义挑战逻辑 } catch (err) { console.error('认证初始化失败', err); } }
- Lambda验证移动端令牌:
- 在
Define Auth ChallengeLambda中,定义名为MOBILE_TOKEN_VERIFICATION的自定义挑战。 - Web端通过Pusher获取移动端发送的access token,调用
Auth.sendCustomChallengeAnswer提交令牌:async function submitMobileToken(userSub, mobileAccessToken) { try { const user = await Auth.sendCustomChallengeAnswer(userSub, mobileAccessToken); console.log('登录成功', user); } catch (err) { console.error('令牌验证失败', err); } } - 在
Verify Auth Challenge ResponseLambda中,调用Cognito的VerifyTokenAPI验证传入的access token,确认其属于该sub的用户,返回验证结果。
- 在
方案三:手动构造Amplify会话(不推荐)
如果是临时需求,可通过手动构造Cognito会话对象绕过Auth.signIn,但该方法依赖Amplify内部实现,版本更新可能失效:
import { Auth } from 'aws-amplify'; // 需要从移动端获取id token、access token、refresh token及对应payload const customSession = { idToken: { jwtToken: mobileIdToken, payload: JSON.parse(atob(mobileIdToken.split('.')[1])), }, accessToken: { jwtToken: mobileAccessToken, payload: JSON.parse(atob(mobileAccessToken.split('.')[1])), }, refreshToken: { token: mobileRefreshToken, }, clockDrift: 0, }; // 覆盖currentSession方法 Auth.currentSession = () => Promise.resolve(customSession); // 后续可正常调用Auth方法 const user = await Auth.currentAuthenticatedUser();
内容的提问来源于stack exchange,提问作者Oleksiy Markin
相关产品推荐
相关产品推荐

