我使用AWS Amplify进行身份验证,使用Stripe进行付款以创建注册页面。
问题:我无法找到将电子邮件和密码部分(来自AWS Amplify)的验证与付款信息部分(来自Stripe)相结合的方法。
我当前的代码创建一个Stripe令牌并调用API(带有有效的付款信息)然后处理来自userSignupRequest
的错误消息,该消息负责电子邮件和密码字段。
如何使用付款信息验证电子邮件和密码,然后在AWS和Stripe中创建帐户?
// Stripe payment process
this.props.stripe.createToken(
{
email: this.state.email
}
).then(result => {
// PROBLEM: Form server validation from Stripe
if(result.error){
return this.setState({ errors: { errorMsg: result.error.message }, isLoading: false })
}
// if success, create customer and subscription with result.token.id
const apiName = 'NameOfAPI';
const path = '/stripe/signup';
let myInit = {
body: {
"stripeToken": result.token.id,
"email": this.state.email
}
}
API.post(apiName , path, myInit).then(reponse => {
this.props.userSignupRequest(this.state.email, this.state.password, reponse).then(user => {
this.setState({
confirmAccount: true,
isLoading: false,
userEmail: this.state.email,
errors: {}
})
this.props.history.push('/signup#confirm-account')
}).catch(err => {
// PROBLEM: Form server validation
this.setState({ errors: { errorMsg: err.message }, isLoading: false })
})
}).catch(err => {
console.log(err)
this.setState({ errors: { errorMsg: err }, isLoading: false })
});
})
答案 0 :(得分:1)
好像我们有一个非常相似的堆栈。我的解决方案是处理服务器端的所有事情。您需要为lambda函数提供适当的IAM权限才能访问Cognito。下面的代码有点长。我使用async/await,它真的为我清理了一些东西。您需要将Lambda与节点8一起使用async / await。
我验证所有内容都符合客户端的正确格式(即电子邮件确实是电子邮件,密码是正确的长度)。我意识到唯一可能出现的错误是来自Cognito的“现有用户”错误。这个想法是:在尝试使用Stripe签名此人之前测试用户是否存在。如果用户的信用卡对Stripe有效,则无法“测试”。这是全有或全无。如果它有效则会通过,如果没有,你会收到错误。如果它通过,您可以使用Cognito注册用户,知道您不应该收到错误(您已经验证了客户端的电子邮件和密码,并且您知道该用户尚未存在)。
供参考,这是aws-sdk for cognito。
const AWS = require('aws-sdk');
const cognito = new AWS.CognitoIdentityServiceProvider({
region: "region",
userPoolId: "cognito_user_pool_id",
});
module.exports.signUpUser = (payload) => {
const usernamePayload = {
UserPoolId: "cognito_user_pool_id",
Username: payload.email,
};
// I use emails for usernames.
new Promise((resolve, reject) => {
cognito.adminGetUser(usernamePayload, (error, response) => {
if (error && error.code === 'UserNotFoundException') {
resolve(false);
} else if (error) {
reject(error);
} else {
// if adminGetUser doesn't fail, it means the username exists
resolve(true);
}
});
}).then((usernameExists) => {
if (!usernameExists) {
// run stripe API stuff
// always run before sign up below to catch stripe errors
// and return those errors to client
// before you sign up the user to Cognito
// since you've already verified the user does not exist
// it would be rare for an error to come up here
// as long as you validate passwords and emails client-side
const signUpPayload = {
ClientId: "cognito_user_pool_client_id",
Username: payload.email,
Password: payload.password,
UserAttributes: [
{
Name: 'email',
Value: payload.email,
},
],
};
new Promise((resolve, reject) => {
cognito.signUp(signUpPayload, (error, response) => {
if (error) {
reject(error);
} else {
resolve(response);
}
});
}).catch((error) => {
// you should hopefully encounter no errors here
// once you get everything setup correctly
console.log(error);
})
} else {
// means username already exists, send error to client
// saying username exists
}
}).catch((error) => {
// may want to dispatch this error to client
console.log(error);
});
return null;
};