Aws Cognito 自定义授权流程
概要
原来有个网站,存在完善的账号管理,现在要增加一个网站,希望能使用统一的账号管理。
理想的方案是增加一个OAuth2服务,两个网站分别接入这个服务。但是由于特别的原因,旧网站只能进行微小的发动,于是要求这个 OAuth2 要能够支持自定义流程以旧网站的顺利接入而且不需要多少的变化。最终选择了使用 AWS Cognito 服务
设计方案
- 使用旧网站的登陆做为主登陆界面,所有的登陆请求重定向到旧网站的登陆界面,并带上来源地址。
- 登陆完成后,跳转到新网站的登陆校验 api 地址
- 在新的网站完成 Cognito 的自定义用户登陆过程来保持用户的统一.
实现过程
新网站中用户管理相关全部 Redirect 到旧网站的相关链接,使用旧有的用户管理和注册登陆不再改变。
旧网站中增加一个链接,用于跳转新网站并告诉新的网站当前登陆的账号
- 新网站增加 Get /auth/sign_in
- 并使用 Cognito 的 initiateAuth 访问 Cognito 获取授权
- 流程 AuthFlow 设定为 CUSTOM_AUTH
- 通过 UserPool 设置 Define Auth Challenge,Create Auth Challenge,Verify Auth Challenge Response 以响应授权询问过程
- 获取授权成功后转跳到首页
旧网站在转跳到新网站时,通过约定的授权方式(api-key)访问该地址,并带上当前登陆的账户标识。
initiateAuth([ 'AuthFlow' => 'CUSTOM_AUTH', 'AuthParameters' => [ 'USERNAME' => <Username>, 'SECRET_HASH' => <hash(ClientId,Username)>, ], 'ClientId' => ClientId, ])
exports.handler = (event, context, callback) => { /** * triggerSource * Define auth challenge DefineAuthChallenge_Authentication Define Auth Challenge. * Create auth challenge CreateAuthChallenge_Authentication Create Auth Challenge. * Verify auth challenge VerifyAuthChallengeResponse_Authentication Verify Auth Challenge Response. * */ const { request, response } = event; const {session} = request; switch (event.triggerSource) { case 'DefineAuthChallenge_Authentication': if (session.length === 0) { // custom auth return token response.issueTokens = true; response.failAuthentication = false; } else { if (session.length == 1 && session[0].challengeName == 'SRP_A') { response.issueTokens = false; response.failAuthentication = false; response.challengeName = 'PASSWORD_VERIFIER'; } else if (session.length == 2 && session[1].challengeName == 'PASSWORD_VERIFIER' && session[1].challengeResult == true) { response.issueTokens = false; response.failAuthentication = false; response.challengeName = 'CUSTOM_CHALLENGE'; } else if (session.length == 3 && session[2].challengeName == 'CUSTOM_CHALLENGE' && session[2].challengeResult == true) { response.issueTokens = true; response.failAuthentication = false; } else { response.issueTokens = false; response.failAuthentication = false; response.challengeName = 'CUSTOM_CHALLENGE'; } } break; case 'CreateAuthChallenge_Authentication': if (request.challengeName == 'CUSTOM_CHALLENGE') { response.publicChallengeParameters = {}; response.publicChallengeParameters.captchaUrl = 'url/123.jpg'; response.privateChallengeParameters = {}; response.privateChallengeParameters.answer = '5'; response.challengeMetadata = 'CAPTCHA_CHALLENGE'; } break; case 'VerifyAuthChallengeResponse_Authentication': if (request.privateChallengeParameters.answer == request.challengeAnswer) { response.answerCorrect = true; } else { response.answerCorrect = false; } break; default: } //Return to Amazon Cognito callback(null, event); };
评论已关闭