【问题标题】:How to handle multiple errors in promise chain?如何处理承诺链中的多个错误?
【发布时间】:2018-11-07 21:09:13
【问题描述】:

我使用 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 })
    });

  })

【问题讨论】:

  • 给你一个服务器端的解决方案可以吗?如果是这样,您是否使用节点,如果使用 - 什么版本?我认为您的解决方案是关于客户端的最佳解决方案。
  • 我正在使用 AWS 放大 API,它使用 Lambda 和节点 6.10

标签: javascript reactjs stripe-payments aws-amplify


【解决方案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;
};

【讨论】:

  • 我正在使用 AWS 移动集线器进行身份验证。设置lambda functions the appropriate IAM permissions to access Cognito 看起来如何?
  • 这对您来说可能变化太大。 AWS 移动正在处理您所有的 cognito 用户池内容。这种方法需要你开始处理其中的一些。您至少需要获取您的“用户池 ID”,并且可能在您的用户池中创建一个应用程序客户端,以获取“客户端 ID”。此外,您必须为 Lambda 函数创建一个 IAM 角色并向该角色附加权限,从而允许访问 Cognito。然后,您需要将此角色添加到您的 Lambda 函数中。如果您查看其中一个 Lambda 函数,应该有一个可以添加 IAM 角色的区域。
  • This guide 展示了如何创建用户池。您可能不需要创建一个,但至少它向您展示了 Cognito 和用户池的工作方式。 This guide 看起来可以帮助为 Lambda 创建 IAM 角色,但我还没有阅读。
  • 基本上,这是我能想到的唯一设置,以防止用户被添加到 Cognito,然后被 Stripe 拒绝(因为他们的信用卡错误等),反之亦然(由 Stripe 收费) ,但是他们的电子邮件已经存在 - 所以他们无法创建一个认知新的认知帐户,现在他们的条带电子邮件是错误的)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-03
  • 2019-09-25
  • 2014-11-22
  • 2014-08-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多