AWS Login Auth
前提
最近接到了一个新的需求,要将应用程序和AWS结合起来,并使用AWS来作为账户的认证。初一看有点像SSO,但是需求方说只需要做校验,登入登出都不作处理,用户信息存在AWS的user pool中。
思考
AWS上IAM和Cognito,IAM可以作为登陆AWS console,身份权限校验比较完善。但是对于这个需求,貌似有点大材小用。因为我只需要管理用户信息,用户并不需要具有AWS相关服务的权限。(权限最小化也是一种保护用户的举措)那么就剩下了Cognito。研究了下Cognito,Cognito提供了两种pool,一种identity user pool,这种可以用来集成IDP服务(第三方登陆,再通俗点就是我用微信,微博作为账号登陆其他系统)。另一种就是普通的management user pool。这种就是账户可以在AWS中创建,但是没有登陆AWS的权限,符合我们的要求。
方案
- 方案一:通过AWS的Lambda function来集成cognito服务。整体流程是:app端输入用户名/密码,调用API gateway(https请求)发给AWS,API gateway调用后续Cognito服务来做身份验证,将用户认证成功的token信息返回给客户端。
- 方案二:采用客户端SDK的方式,将认证的相关函数集成在客户端,通过SDK向AWS发送请求。认证通过后,返回token。
方案挑选
- 方案一是我门一开始极力推从的,原因是客户端只需要极少的代码,一个https请求就可以,其他的都交给AWS来做。这样我们整体的app包不会很大,但是难点在于API gateway集成验证,这个地方并没有吃透。无法debug。
- 方案二可行,技术上不存在问题,有个不好的地方在于需要在客户端安装SDK,这个包还不小(几兆),而且真正应用的时候其实并不需要那么全的功能。
实战
用React画登陆页面着实不是件简单的事,画components要吐了(想想还是UX好,工具生成),编码还是比较容易。中间遇到了一个问题是用户做校验的时候,如果是首次登陆必须要更改密码(别问为什么,AWS规定的),那么我又没有修改密码的功能怎么办?如果有修改密码的,势必还要有(邮件,短信验证码功能...),无异于增加了scope,带来了复杂。抖机灵(用户第一次去校验的时候会返回需要修改密码的error,那么我改两次,把密码再改回去就好了)实践了一下,还真ok。验证模块代码可参考https://github.com/aws-amplify/amplify-js/tree/master/packages/amazon-cognito-identity-js
const authUser=(cognitoUser,authenticationDetails,password,callback)=>{
var isFirstLogin = false;
cognitoUser.authenticateUser(authenticationDetails,
{
onSuccess: function (result) {
// console.log('result' + JSON.stringify(result))
if(isFirstLogin){
cognitoUser.changePassword(tempPassword, password,(err,result)=>{});
// console.log(' cognitoUser.changePassword')
isFirstLogin = false;
}
var token = result.getAccessToken().getJwtToken();
// console.log('token: ' + token)
callback(null, token)
// return token
},
onFailure: function (err) {
//console.log("auth fail:" + err.message || JSON.stringify(err))
callback('err',err.message)
// return err
},
newPasswordRequired: function (userAttributes, requiredAttributes) {
cognitoUser.completeNewPasswordChallenge(tempPassword, null,this);
// console.log(' cognitoUser.completeNewPasswordChallenge')
isFirstLogin = true;
}
})
}
good
总结
有些时候多想想,带着问题去研究,效果显著。当一条路走不通的时候,不妨看看旁边被自己忽视的路。
PS:中秋节快乐!