基于Serverless Framework实现AWS Cognito用户认证API的可行性及示例咨询
绝对可行!用Serverless Framework + AWS Cognito + Lambda构建用户认证API
当然可以!Serverless Framework天生就是为AWS这类云服务的无服务器部署设计的,完全能帮你快速搭建连接Cognito的Lambda函数,实现用户注册、认证、修改密码这些核心API。下面我给你一套完整的可参考示例,从配置到代码都给你捋清楚。
第一步:编写Serverless配置文件(serverless.yml)
这是整个项目的核心配置,我们要在这里定义Lambda函数、IAM权限、API Gateway端点,以及和Cognito的关联:
service: cognito-user-api provider: name: aws runtime: nodejs18.x region: us-east-1 # 替换成你的AWS区域 environment: USER_POOL_ID: "your-user-pool-id" # 替换成你的Cognito用户池ID CLIENT_ID: "your-app-client-id" # 替换成你的Cognito应用客户端ID iamRoleStatements: - Effect: Allow Action: - cognito-idp:SignUp - cognito-idp:InitiateAuth - cognito-idp:ChangePassword Resource: "arn:aws:cognito-idp:${self:provider.region}:${aws:accountId}:userpool/${self:provider.environment.USER_POOL_ID}" functions: registerUser: handler: handler.register events: - http: path: /register method: post cors: true loginUser: handler: handler.login events: - http: path: /login method: post cors: true changeUserPassword: handler: handler.changePassword events: - http: path: /change-password method: post cors: true
解释下关键部分:
- 我们通过
iamRoleStatements给Lambda函数分配了访问Cognito的必要权限,刚好覆盖你需要的三个操作 - 用环境变量存储Cognito的ID信息,避免硬编码敏感数据
- 每个函数都绑定了API Gateway的POST端点,并且开启了CORS方便前端调用
第二步:Lambda函数代码实现(handler.js)
接下来写具体的业务逻辑,我们把三个函数都放在同一个handler文件里:
const AWS = require('aws-sdk'); const cognito = new AWS.CognitoIdentityServiceProvider({ region: process.env.AWS_REGION }); // 用户注册 module.exports.register = async (event) => { try { const { email, password, username } = JSON.parse(event.body); const params = { ClientId: process.env.CLIENT_ID, Username: username, Password: password, UserAttributes: [ { Name: 'email', Value: email } ] }; const result = await cognito.signUp(params).promise(); return { statusCode: 200, body: JSON.stringify({ message: '用户注册成功', userSub: result.UserSub }) }; } catch (error) { return { statusCode: error.statusCode || 500, body: JSON.stringify({ message: error.message || '注册失败' }) }; } }; // 用户认证登录 module.exports.login = async (event) => { try { const { username, password } = JSON.parse(event.body); const params = { AuthFlow: 'USER_PASSWORD_AUTH', ClientId: process.env.CLIENT_ID, AuthParameters: { USERNAME: username, PASSWORD: password } }; const result = await cognito.initiateAuth(params).promise(); return { statusCode: 200, body: JSON.stringify({ message: '登录成功', tokens: { idToken: result.AuthenticationResult.IdToken, accessToken: result.AuthenticationResult.AccessToken, refreshToken: result.AuthenticationResult.RefreshToken } }) }; } catch (error) { return { statusCode: error.statusCode || 500, body: JSON.stringify({ message: error.message || '登录失败' }) }; } }; // 修改密码 module.exports.changePassword = async (event) => { try { const { accessToken, oldPassword, newPassword } = JSON.parse(event.body); const params = { AccessToken: accessToken, PreviousPassword: oldPassword, ProposedPassword: newPassword }; await cognito.changePassword(params).promise(); return { statusCode: 200, body: JSON.stringify({ message: '密码修改成功' }) }; } catch (error) { return { statusCode: error.statusCode || 500, body: JSON.stringify({ message: error.message || '密码修改失败' }) }; } };
一些额外的建议
- 替换敏感信息:一定要把配置里的
USER_POOL_ID和CLIENT_ID换成你自己Cognito实例的对应值 - 输入验证:生产环境里建议给每个接口加输入验证(比如密码复杂度、邮箱格式检查),可以用Joi这类库
- 错误处理:可以根据Cognito返回的具体错误码(比如
UsernameExistsException)返回更友好的提示 - 安全优化:可以给API Gateway开启API密钥认证,或者用WAF做防护,提升接口安全性
部署的时候,只要在项目根目录运行serverless deploy就能把整个服务部署到AWS上了,非常方便!
内容的提问来源于stack exchange,提问作者Rahul
相关产品推荐
相关产品推荐

