aws cognito_AWS Cognito的用户管理—(2/3)核心功能

aws cognito

by Kangze Huang

黄康泽

AWS Cognito的用户管理—(2/3)核心功能 (User Management with AWS Cognito — (2/3) The Core Functionality)

完整的AWS Web样板-教程1B (The Complete AWS Web Boilerplate — Tutorial 1B)

Main Table of Contents Click Here

主要目录请点击这里

Part A: Initial Setup

A部分: 初始设置

Part B: The Core Functionality

B部分: 核心功能

Part C: Last Steps to Full Fledged

C部分: 全面完成的最后步骤

Download the Github here.

在此处下载Github。

Javascript Cognito SDK (The Javascript Cognito SDK)

Great! You should only be here if you finished the initial setup for Cognito and Federated Identities. Now that we have everything set up, its time to walk through the Javascript code. Download the Kangzeroo boilerplate on Github and be sure to enter the Cognito branch where we will be doing our work.

大! 仅当您完成Cognito和联合身份的初始设置时,您才应该在这里。 现在我们已经完成了所有的设置,接下来可以遍历Javascript代码了。 在Github上下载Kangzeroo样板,并确保进入Cognito分支,我们将在那里开展工作。

$ git clone https://github.com/kangzeroo/Kangzeroos-Complete-AWS-Web-Boilerplate.git$ cd Kangzeroos-Complete-AWS-Web-Boilerplate$ git checkout Cognito$ cd App

The boilerplate uses the Amazon-Cognito-Identity-JS library found on github. This library makes it really easy to use programatic AWS Cognito, but the same functionality can be found in the native aws-sdk. So let’s go and install our dependencies and load up the app.

该样板使用在github上找到的Amazon-Cognito-Identity-JS库 。 该库使使用编程的AWS Cognito变得非常容易,但是可以在本机aws-sdk找到相同的功能。 因此,让我们开始安装依赖项并加载应用程序。

$ npm install$ npm run start

AWS配置文件设置 (AWS Profile Setup)

Navigate to App/src/components/Auth where we will find all the React components related to Cognito authentication. Yes, this tutorial uses React, but you can easily apply the same lessons to other JS frameworks. Go to App/src/api/aws/aws-cognito.js which is where the bulk of the AWS Cognito code resides. Let’s take a look at the dependencies and how we can setup our own AWS profile.

导航到App/src/components/Auth ,在这里我们将找到与Cognito身份验证相关的所有React组件。 是的,本教程使用React,但是您可以轻松地将相同的课程应用于其他JS框架。 转到App/src/api/aws/aws-cognito.js ,这是大量AWS Cognito代码所在的位置。 让我们看一下依赖关系以及如何设置自己的AWS配置文件。

// aws-cognito.js
import { CognitoUserPool, CognitoUserAttribute, CognitoUser, AuthenticationDetails, CognitoIdentityCredentials, WebIdentityCredentials } from 'amazon-cognito-identity-js';
import { userPool, LANDLORD_USERPOOL_ID, LANDLORD_IDENTITY_POOL_ID, TENANT_IDENTITY_POOL_ID } from './aws_profile'
import uuid from 'node-uuid'

We import a variety of functions from amazon-cognito-identity-js as well as from ./aws_profile.js. The functions from amazon-cognito-identity-js will be explained as we go along. What we want to focus on is the ./aws_profile.js stuff. Here is where we put our Cognito params such as our userPoolId and AppIds. Let’s take a look at ./aws_profile.js.

我们进口的各种功能,从amazon-cognito-identity-js以及来自./aws_profile.js 。 我们将逐步解释来自amazon-cognito-identity-js的功能。 我们要重点关注的是./aws_profile.js 。 这是我们放置Cognito参数的地方,例如userPoolId和AppIds。 让我们看一下./aws_profile.js

import { CognitoUserPool } from 'amazon-cognito-identity-js';import 'amazon-cognito-js'
const REGION = "us-east-1"const USER_POOL_ID = 'us-east-1_6i5p2Fwao'const CLIENT_ID = '5jr0qvudipsikhk2n1ltcq684b'
AWS.config.update({ region: REGION})
const userData = {    UserPoolId : USER_POOL_ID,    ClientId : CLIENT_ID}
export const userPool = new CognitoUserPool(userData);
export const USERPOOL_ID = 'cognito-idp.'+REGION+'.amazonaws.com/'+USER_POOL_ID
export const IDENTITY_POOL_ID = 'us-east-1:65bd1e7d-546c-4f8c-b1bc-9e3e571cfaa7'

Here we are setting up our AWS region, Cognito USER_POOL_ID, and Cognito App CLIENT_ID. We are also creating a CognitoUserPool object from our USER_POOL_ID and CLIENT_ID, which holds the bulk of our Cognito functions. CognitoUserPool has functions for everything ranging from password resets to authenticating a new user. We create CognitoUserPool here so that we don’t have to re-instantiate it again for each function. We also set up our USERPOOL_ID which is a url that is required in some Cognito functions, and comprised of USER_POOL_ID and region. Finally, we also export a ARN of our Federated Identities pool, which is also required in some Cognito functions. All in all, this is just setup and you only need to copy and paste your own values.

在这里,我们将设置我们的AWS region ,Cognito USER_POOL_ID和Cognito应用程序CLIENT_ID 。 我们还将根据USER_POOL_IDCLIENT_ID创建一个CognitoUserPool对象,该对象包含大部分Cognito函数。 CognitoUserPool具有从密码重置到验证新用户的所有功能。 我们在这里创建CognitoUserPool ,这样我们就不必为每个函数再次实例化它。 我们还设置了USERPOOL_ID ,它是某些Cognito函数所需的URL,由USER_POOL_IDregion 。 最后,我们还导出了联邦身份池的ARN,这在某些Cognito功能中也是必需的。 总而言之,这只是设置,您只需要复制并粘贴自己的值即可。

Last setup set, we will create an array of our user attributes at the top of our aws_cognito.js file. Fill in the array with your own user attributes, and don’t forget to prefix any custom attributes with custom: for const attrs. const landlordAttrs does not require the custom: prefix.

最后设置集,我们将在aws_cognito.js文件的顶部创建一个用户属性数组。 用自己的用户属性阵列中的填充,并且不要忘记前缀任何自定义属性custom:用于const attrsconst landlordAttrs不需要custom:前缀。

// we create an array of all attributes, without the `custom:` prefix. // This will be used for building the React-Redux object in plain JS, hence no AWS Cognito related name requirementsconst landlordAttrs = ["email", "agentName", "id"]
// we create an array of all our desired attributes for changing, and we loop through this array to access the key name.// This will be used for AWS Cognito related name requirementsconst attrs = ["custom:agentName"]

Now after setup and before beginning the actual code, I should say that this boilerplate is complete. You don’t necessarily need to know what’s going on behind the scenes. You can just use this boilerplate and all features will work out of the box: signup, login, email verification, password reset, user attribute changes and saved logins using JWT. Note that any emails you use in Cognito must be verified by AWS, until you request to leave the AWS SES sandbox (in which case you will be able to message any email). If you’re here for just the working boilerplate, this is as far as you need to read. If you want to know what’s going on, continue reading!

现在,在设置之后,在开始实际代码之前,我应该说这个样板已经完成。 您不一定需要了解幕后情况。 您可以仅使用此样板,所有功能将立即可用:注册,登录,电子邮件验证,密码重置,用户属性更改以及使用JWT保存的登录信息。 请注意,您在Cognito中使用的所有电子邮件都必须经过AWS的验证,直到您请求离开AWS SES沙箱 (在这种情况下,您将能够向任何电子邮件发送消息)。 如果您只是在这里工作样板,这是您需要阅读的内容。 如果您想知道发生了什么,请继续阅读!

注册用户 (Sign Up Users)

Let’s look at the first auth component called SignUp.js. I won’t spend time explaining the React side of things, as that is not the purpose of this tutorial. Go find this function:

让我们看一下第一个名为SignUp.js身份验证组件。 我不会花时间解释事物的React方面,因为这不是本教程的目的。 去找到这个功能:

signup(){
...
// call the AWS Cognito function that we named `signUpUser`    signUpUser(this.state)     .then(({email})=>{      // if successful, then save the email to localStorage so we can pre-fill the email form on the login & verify account screens      localStorage.setItem('User_Email', email)      // re-route to the verify account screen      browserHistory.push('/auth/verify_account')     })
...
}

Here we are calling signUpUser() and passing in the React component state, which looks like this:

在这里,我们调用signUpUser()并传递React组件状态,如下所示:

this.state = {   email: "",   agentName: "",   password: "",   confirmPassword: "",   errorMessage: null,   loading: false}

We will only be using the email and password attributes of the state when we pass it into signUpUser(). ThesignUpUser() function is located in App/src/api/aws/aws-cognito.js.

将状态传递给signUpUser()时,我们将仅使用状态的电子邮件和密码属性。 signUpUser()函数位于App/src/api/aws/aws-cognito.js

export function signUpUser({email, agentName, password}){ const p = new Promise((res, rej)=>{
const attributeList = []
const dataEmail = {      Name : 'email',      Value : email  }  const dataAgentName = {      Name : 'custom:agentName',      Value : agentName  }
const attributeEmail = new CognitoUserAttribute(dataEmail)  const attributeAgentName = new CognitoUserAttribute(dataAgentName)
attributeList.push(attributeEmail, attributeAgentName)
userPool.signUp(email, password, attributeList, null, function(err, result){      if (err) {          rej(err)          return      }      res({email})  }) }) return p}

signUpUser() accepts an object that should have 3 attributes: email, password and agentName. In order to save it as an attribute of our Cognito user, we must make a CognitoUserAttribute object for each. We do this by creating a dataEmail and dataAgentName object with the name of the attribute and its value. These objects will be passed into the CognitoUserAttribute function that converts it into AWS Cognito readable objects that we have titled attributeEmail and attributeAgentName. Note that dataAgentName.name is prefixed with custom: to specify to Cognito that agentName is a custom user attribute. Now that we have our CognitoUserAttribute objects, we will push them into the attributeList array.

signUpUser()接受一个对象,该对象应具有3个属性: emailpasswordagentName 。 为了将其保存为Cognito用户的属性,我们必须为每个用户创建一个CognitoUserAttribute对象。 为此,我们创建了一个带有属性名称及其值的dataEmaildataAgentName对象。 这些对象将传递到CognitoUserAttribute函数,该函数将其转换为AWS Cognito可读对象,我们将其命名为attributeEmailattributeAgentName 。 请注意, dataAgentName.name带有custom:前缀,以向Cognito指定agentName是自定义用户属性。 现在我们有了CognitoUserAttribute对象,我们将它们推入attributeList数组。

The next line of code is what actually registers this new user. We use the userPool object that we imported from ./aws_profile.js and call its signUp function. The first 3 arguments are the unique identifier email, password, and the attributeList array. The fourth argument is null, and the fifth is the callback. In the callback, we reject the promise if an error occurred, and if no errors, then we resolve the promise. In the boilerplate, we return the email to be saved to localStorage in our React component, but this is not mandatory. You can resolve the promise with nothing. The new Cognito user has been created. But in order to use the new user, they need to be able to verify their account. The AWS infrastructure for this has already been set up, so now all we have to do is walk through the code of the verification function.

下一行代码是实际注册此新用户的代码。 我们使用从./aws_profile.js导入的userPool对象,并调用其signUp函数。 前三个参数是唯一标识符emailpasswordattributeList数组。 第四个参数为null,第五个为回调。 在回调中,如果发生错误,我们将拒绝承诺,如果没有错误,则我们将解决承诺。 在样板中,我们将电子邮件保存到React组件中,并将其保存到localStorage中,但这不是强制性的。 您什么也无法解决。 新的Cognito用户已创建。 但是,为了使用新用户,他们需要能够验证其帐户。 为此已经建立了AWS基础架构,因此现在我们要做的就是浏览验证功能的代码。

验证账户 (Verify Account)

We won’t be spending too much time on this part of the code, so I will first explain the React-Redux component at a high level, and then go into detail with the AWS stuff.

我们不会在代码的这一部分上花费太多时间,因此我将首先在较高级别上解释React-Redux组件,然后再详细介绍AWS内容。

At a high level what happens after a user signs up is that they are redirected by react-router to the /verify_account url where the App/src/components/Auth/VerifyAccount.js component appears. When the component is mounted, the email field is auto-filled by accessing the localStorage. Then we have the option to enter the verification PIN sent to the user’s email, or choose to reset & resend the verification PIN. Let’s take a look at the resetVerificationPIN() function in App/src/api/aws/aws-cognito.js.

在较高级别上,用户注册后发生的情况是,他们通过react-router重定向到/verify_account网址,其中出现了App/src/components/Auth/VerifyAccount.js组件。 装入组件后,将通过访问localStorage来自动填充电子邮件字段。 然后,我们可以选择输入发送到用户电子邮件的验证码,或选择重置并重新发送验证码。 让我们看看App/src/api/aws/aws-cognito.js中的resetVerificationPIN()函数。

export function resetVerificationPIN(email){ const p = new Promise((res, rej)=>{  const userData = {   Username: email,   Pool: userPool  }  const cognitoUser = new CognitoUser(userData)  cognitoUser.resendConfirmationCode(function(err, result) {         if (err) {          rej(err)          return         }         res()     }) }) return p}

When we call this function, we only need to pass in the email. Cognito will automatically check that the email exists and throw an error if it does not. Like in SignUp.js, we create a userData object containing our user’s email and the userPool imported from ./aws_profile.js in order to create a vliad CognitoUser object. Using CognitoUser object, we can call resendConfirmationCode() to have the PIN be sent again. And that’s it!

当我们调用此函数时,我们只需要传递电子邮件即可。 Cognito将自动检查电子邮件是否存在,如果不存在,则会引发错误。 像在SignUp.js一样,我们创建一个userData对象,其中包含用户的电子邮件和从./aws_profile.js导入的./aws_profile.js ,以便创建一个可变的CognitoUser对象。 使用CognitoUser对象,我们可以调用resendConfirmationCode()以再次发送PIN。 就是这样!

Now let’s look at the verifyUserAccount() function:

现在让我们看一下verifyUserAccount()函数:

export function verifyUserAccount({email, pin}){ const p = new Promise((res, rej)=>{  const userData = {   Username: email,   Pool: userPool  }  const cognitoUser = new CognitoUser(userData)  cognitoUser.confirmRegistration(pin, true, function(err, result) {         if (err) {             console.log(err);             rej(err)             return;         }         if(result == "SUCCESS"){          console.log("Successfully verified account!")          cognitoUser.signOut()          res()         }else{          rej("Could not verify account")         }     }) }) return p}

verifyUserAccount() accepts an object as its only argument, containing 2 essential attributes email and pin. We create another userData object to create a CognitoUser in order to call the confirmRegistration() function. In confirmRegistration() we pass in the pin, true, and a callback. If the confirmation succeeds, then we log out the cognitoUser (so that we can login again and refresh the user). If it fails, then we reject the promise. Pretty easy since the SDK has abstracted a lot of the details. Upon successful verification, the React component should re-direct you to the Login page.

verifyUserAccount()接受一个对象作为其唯一参数,其中包含2个基本属性emailpin 。 我们创建另一个userData对象来创建CognitoUser ,以调用confirmRegistration()函数。 在confirmRegistration()我们传入pintrue和回调。 如果确认成功,则我们注销cognitoUser(以便我们可以再次登录并刷新用户)。 如果失败,我们将拒绝承诺。 由于SDK提取了许多细节,因此非常容易。 成功验证后,React组件应将您重定向到“登录”页面。

登录用户 (Sign In Users)

Let’s look at the next component App/src/components/Auth/Login.js. Find the following function:

让我们看下一个组件App/src/components/Auth/Login.js 。 查找以下功能:

signin(){  this.setState({loading: true})  signInUser({   email: this.state.email,   password: this.state.password  }).then((userProfileObject)=>{   localStorage.setItem('User_Email', this.state.email)   this.props.setUser(userProfileObject)   browserHistory.push('/authenticated_page')  })  .catch((err)=>{   this.setState({    errorMessage: err.message,    loading: false   })  }) }

What is happening here? First we call the signInUser() Cognito function to sign in and grab user details from Cognito. Next in the promise chain, we save the user email to localStorage so that we can automatically set the email next login. We also save the user to the Redux state using this.props.setUser(), which is a Redux action function located at App/src/actions/auth_actions.js. We won’t cover the React-Redux stuff as it is not the focus of this tutorial. Let’s look at the AWS Cognito function.

这是怎么回事 首先,我们调用signInUser() Cognito函数来登录并从Cognito获取用户详细信息。 在Promise链的下一步,我们将用户电子邮件保存到localStorage以便我们可以在下次登录时自动设置电子邮件。 我们还使用this.props.setUser()将用户保存到Redux状态,这是位于App/src/actions/auth_actions.js的Redux操作函数。 我们不会介绍React-Redux,因为它不是本教程的重点。 让我们看一下AWS Cognito函数。

Find signInUser() at App/src/api/aws/aws-cognito.js. This is what it looks like:

App/src/api/aws/aws-cognito.js找到signInUser() 。 看起来是这样的:

export function signInUser({email, password}){ const p = new Promise((res, rej)=>{
const authenticationDetails = new AuthenticationDetails({   Username: email,   Password: password  })
const userData = {   Username: email,   Pool: userPool  }  const cognitoUser = new CognitoUser(userData)
authenticateUser(cognitoUser, authenticationDetails)   .then(()=>{    return buildUserObject(cognitoUser)   })   .then((userProfileObject)=>{    res(userProfileObject)   })   .catch((err)=>{    rej(err)   })
}) return p}

We create an AuthenticationDetails Cognito object containing the user email and password. We also create a CognitoUser object to use for its authenticateUser() function, but notice authenticateUser() is not declared anywhere in the function or at the top of the page where we list dependencies. This is because authenticateUser() is another function declared further down the page. Another function declared in the page is buildUserObject(), which takes the user attributes from Cognito and formats them into a user object that we want to use in the Redux state. At the end of the promise chain, we return the userProfileObject that buildUserObject() outputs. Let’s walk through the promise chain starting with authenticateUser().

我们创建一个AuthenticationDetails Cognito对象,其中包含用户emailpassword 。 我们还创建了一个CognitoUser对象用于其authenticateUser()函数,但请注意,在该函数中的任何地方或在列出依赖项的页面顶部都未声明authenticateUser() 。 这是因为authenticateUser()是在页面下方声明的另一个函数。 页面中声明的另一个函数是buildUserObject() ,它从Cognito获取用户属性并将其格式化为我们要在Redux状态下使用的用户对象。 在承诺链的末尾,我们返回buildUserObject()输出的userProfileObject 。 让我们遍历从authenticateUser()开始的承诺链。

function authenticateUser(cognitoUser, authenticationDetails){ const p = new Promise((res, rej)=>{
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: function (result) {             localStorage.setItem('user_token', result.accessToken.jwtToken)             const loginsObj = {                 [USERPOOL_ID]: result.getIdToken().getJwtToken()             }       AWS.config.credentials = new AWS.CognitoIdentityCredentials({                 IdentityPoolId : IDENTITY_POOL_ID,                  Logins : loginsObj             })             AWS.config.credentials.refresh(function(){              console.log(AWS.config.credentials)             })             res()         },
onFailure: function(err) {             rej(err)         }
})
}) return p}

authenticateUser() takes the cognitoUser and authenticationDetails arguments and uses it for 2 things. cognitoUser has a function in it called authenticateUser() which we will call for logging into AWS Cognito. The first argument we pass in is authenticationDetails (which contains the email+password), and the second argument is an object with a onSuccess and onFailure callback. Pretty straightforward, onFailure will simply reject the promise chain. onSuccess will contain result, which will have a JWT token used for future authentication without needing to enter a password. We save the JWT to localStorage and retrieve it whenever we need it (backend authentication for resources or automatic login). Next we create a loginsObj which contains a key-value of our USER_POOL_ID and the JWT token. We pass in this loginsObj to an instance of AWS.config.credentials using new AWS.CognitoIdentityCredentials(), along with the IdentityPoolId. What this does is register a login with AWS Federated Identities. Recall that Federated Identities is used for managing logins from multiple sources, so it makes sense that we use Federated Identities to record a login success per each login.

authenticateUser()接受cognitoUserauthenticationDetails参数,并将其用于两件事。 cognitoUser有一个名为authenticateUser()的函数,我们将调用该函数登录到AWS Cognito。 我们传入的第一个参数是authenticationDetails (包含电子邮件和密码),第二个参数是具有onSuccessonFailure回调的对象。 很简单, onFailure只会拒绝承诺链。 onSuccess将包含result ,它将具有一个JWT令牌,该令牌用于将来的身份验证,而无需输入密码。 我们将JWT保存到localStorage并在需要时检索它(资源的后端身份验证或自动登录)。 接下来,我们创建一个loginsObj ,其中包含我们USER_POOL_ID和JWT令牌。 我们通过这个loginsObj到的实例AWS.config.credentials使用new AWS.CognitoIdentityCredentials()与一起IdentityPoolId 。 这是在AWS Federated Identities中注册登录名。 回想一下,联合身份用于管理来自多个来源的登录,因此有意义的是,我们使用联合身份来记录每个登录的登录成功。

After setting up AWS.config.credentials, we can now use the Cognito authentication to request other Amazon services. Of course those services need to be configured to whitelist a certain Cognito auth (and reject other requests), but that will be shown in future tutorials on a per-service basis. Anyways, after we setup AWS.config.credentials it is important to refresh the credentials using AWS.config.credentials.refresh so that AWS will use the latest one we just added.

设置AWS.config.credentials ,我们现在可以使用Cognito身份验证来请求其他Amazon服务。 当然,需要将这些服务配置为将某个Cognito身份验证列入白名单(并拒绝其他请求),但这将在以后的教程中按服务显示。 无论如何,在设置AWS.config.credentials之后,使用AWS.config.credentials.refresh刷新凭证非常重要,这样AWS才能使用我们刚刚添加的最新凭证。

Now let’s move on to the next step in the signInUser() promise chain: buildUserObject().

现在,让我们继续进行signInUser()承诺链的下一步: buildUserObject()

function buildUserObject(cognitoUser){ const p = new Promise((res, rej)=>{  cognitoUser.getUserAttributes(function(err, result) {         if (err) {              rej(err)              return         }         let userProfileObject = {}         for (let i = 0; i < result.length; i++) {           if(result[i].getName().indexOf('custom:') >= 0){              let name = result[i].getName().slice(7, result[i].getName().length)              userProfileObject[name] = result[i].getValue()           }else{              userProfileObject[result[i].getName()] = result[i].getValue()           }         }         res(userProfileObject)     }) }) return p}

First the cognitoUser object is passed in and used to call its getUserAttributes() method. Like always, we reject the promise if an error occurs. If success, then we proceed to create an emptyuserProfileObject that will have a structure matching what we want on our React-Redux front end. The result object that we get from the success callback is an array of CognitoUserAttribute objects (recall theAttributeList array from signUpUser()). We iterate through this array using a for-loop and get the names of each attribute, stripping away the custom: prefix if needed. Then we also include the value of the attribute, and add the key-value pair to the userProfileObject. By the end of the loop, we will have our finished userProfileObject in plain JS. We return the userProfileObject and complete the signInUser() promise chain. Let’s see the signInUser() flow again and observe the flow at a high level.

首先,将cognitoUser对象传入并用于调用其getUserAttributes()方法。 与往常一样,如果发生错误,我们将拒绝承诺。 如果成功,那么我们将继续创建一个空的userProfileObject ,其结构将与我们在React-Redux前端上想要的结构相匹配。 我们从成功回调中获得的result对象是CognitoUserAttribute对象的数组(从signUpUser()调用AttributeList数组)。 我们使用for循环遍历此数组,并获取每个属性的名称,并在需要时除去custom:前缀。 然后,我们还包括属性的值,并将键值对添加到userProfileObject 。 在循环结束之前,我们将使用纯JS完成我们的userProfileObject 。 我们返回userProfileObject并完成signInUser()承诺链。 让我们再次查看signInUser()流,并从高层次观察该流。

export function signInUser({email, password}){ const p = new Promise((res, rej)=>{
const authenticationDetails = new AuthenticationDetails({   Username: email,   Password: password  })
const userData = {   Username: email,   Pool: userPool  }  const cognitoUser = new CognitoUser(userData)
authenticateUser(cognitoUser, authenticationDetails)   .then(()=>{    return buildUserObject(cognitoUser)   })   .then((userProfileObject)=>{    res(userProfileObject)   })   .catch((err)=>{    rej(err)   })
}) return p}

When we finally resolve the signInUser() promise, we return the userProfileObject to the React component. In the React component Login.js, observe what we do after signInUser().

当我们最终解决signInUser()承诺时,我们将userProfileObject返回到React组件。 在React组件Login.js ,观察一下signInUser()之后的signInUser()

signin(){  this.setState({loading: true})  signInUser({   email: this.state.email,   password: this.state.password  }).then((userProfileObject)=>{   localStorage.setItem('User_Email', this.state.email)   this.props.setUser(userProfileObject)   browserHistory.push('/authenticated_page')    })  .catch((err)=>{   this.setState({    errorMessage: err.message,    loading: false   })  }) }

We save the user’s email to localStorage for future use, and add the userProfileObject to the Redux state. If any errors occurred in the entire process, they will be caught and displayed in this.state.errorMessage. And that’s it! A quick note to point out: this.props.setUser() is a Redux action that will set the userProfileObject to be accessible throughout the Redux app, we well as toggle a boolean state.auth.authenticated to true. The Redux app uses state.auth.authenticated as a means of determining whether a certain page should be rendered or not. For example, we only want to show a user profile page if there is a user logged in.

我们将用户的电子邮件保存到localStorage以供将来使用,并将userProfileObject添加到Redux状态。 如果在整个过程中发生任何错误,它们将被捕获并显示在this.state.errorMessage 。 就是这样! 需要快速指出的一点是: this.props.setUser()是Redux动作,它会将userProfileObject设置为可在整个Redux应用程序中访问,我们还可以将boolean state.auth.authenticated切换为true 。 Redux应用程序使用state.auth.authenticated作为确定是否应呈现某个页面的一种方式。 例如,我们只想在有用户登录时显示用户个人资料页面。

总结第二部分 (Wrapping Up Part 2)

Wow, this has been a long article! But we’re not done yet. There are a few more topics we need to cover, including updateUserInfo(), forgotPassword(), retrieveUserFromLocalStorage(), signOutUser() and backend authentication of JWT tokens for restricted resources. I did say this was a COMPLETE AWS tutorial didn’t I? Anyways, continue reading if you feel like you need to know what’s happening under the hood. Just remember that at any time, you can stop reading and just use the boilerplate as is and it will just work. I hope you have found this series useful so far. See you in Cognito Part 3!

哇,这篇文章很长! 但是我们还没有完成。 我们还需要讨论其他一些主题,包括updateUserInfo()forgotPassword()retrieveUserFromLocalStorage()signOutUser()以及对受限资源的JWT令牌的后端身份验证。 我确实说这是一个完整的AWS教程,不是吗? 无论如何,如果您觉得自己需要了解幕后发生的事情,请继续阅读。 只要记住,您随时都可以停止阅读,只需按原样使用样板就可以了。 希望到目前为止,您对本系列文章有所帮助。 Cognito第三部分见!

Main Table of Contents Click Here

主要目录请点击这里

Part A: Initial Setup

A部分: 初始设置

Part B: The Core Functionality

B部分: 核心功能

Part C: Last Steps to Full Fledged

C部分: 全面完成的最后步骤

These methods were partially used in the deployment of renthero.ca

这些方法部分地用于了renthero.ca的部署中

翻译自: https://www.freecodecamp.org/news/user-management-with-aws-cognito-2-3-the-core-functionality-ec15849618a4/

aws cognito

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/395830.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python字符串后面添加字符串_什么是字符串?怎样在Python中添加字符串?

字符串是一种表示文本的数据类型&#xff0c;字符串中的字符可以是ASCII字符、各种符号以及各种Unicode字符。Python中的字符串有如下三种表现方式。第1种方式&#xff1a;使用单引号包含字符。示例代码如下&#xff1a;a 123注意&#xff0c;单引号表示的字符串里不能包含单引…

surround360

1.读入配置文件2.创建底部和顶部投影线程3.将侧面图投影到球座标(1)load侧面相机图像(2)创建投影线程(3)等待线程结束4.渲染立体全景图(侧边)(1)计算重叠区域宽度(2)创建准备生成新视图的线程: 送入相邻两个相机的投影图,计算光流flowLtoR,flowRtoL, 保存在novelViewGenerators…

snapchat_我刚刚在Snapchat获得开发人员职位。

snapchatby Jon Deng乔恩邓 我刚刚在Snapchat获得开发人员职位。 这是我学到的东西&#xff0c;以及它如何帮助您进行求职。 (I just got a developer job at Snapchat. Here’s what I learned and how it can help you with your job search.) About a year ago, while depl…

sys.argv

import sysi0 print len(sys.argv) while i < len(sys.argv):print sys.argv[%d]:%s %(i,sys.argv[i])i i1 import sysprint len(sys.argv) for i in range(len(sys.argv)):print sys.argv[%d]:%s %(i,sys.argv[i]) 执行 结果 &#xff1a;E:\MyScript>python sysargs.py…

Docker安装java-Zookeeper进行操作

Docker安装Zookeeper下载Zookeeper镜像 docker pull zookeeper启动容器并添加映射 docker run --privilegedtrue -d --name zookeeper --publish 2181:2181 -d zookeeper:latest 查看容器是否启动 docker ps idea提供了一个Zookeeper插件&#xff0c;以供连接Zookeeper服务中心…

java反射获取注解_Java自定义注解和运行时靠反射获取注解

java自定义注解Java注解是附加在代码中的一些元信息&#xff0c;用于一些工具在编译、运行时进行解析和使用&#xff0c;起到说明、配置的功能。注解不会也不能影响代码的实际逻辑&#xff0c;仅仅起到辅助性的作用。包含在 java.lang.annotation 包中。1、元注解元注解是指注解…

进程间的通讯(IPC)方式

内存映射 为什么要进行进程间的通讯(IPC (Inter-process communication)) 数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程&#xff0c;发送的数据量在一个字节到几M字节之间共享数据&#xff1a;多个进程想要操作共享数据&#xff0c;一个进程对共享数据的修改&a…

开发人员避免编写测试的2个最常见原因

This post was originally published on Medium这篇文章最初发表于Medium Writing tests represents one of those few stages of software development that is usually overlooked, even though it may be one of the most important one. Developers mention it and usuall…

java ews_Java---使用EWS 写个ExchangeMailUtil

依赖包&#xff1a;commons-httpclient-3.1.jarcommons-codec-1.10.jarcommons-logging-1.2.jarjcifs-1.3.17.jar代码示例&#xff1a;创建MailBean类&#xff1a;import java.util.Date;public class MailBean {public BigDecimal getId() {return id;}public void setId(BigD…

Ilya Muromets(DP or 思维)

Ilya Muromets Gym - 100513F Силачом слыву недаром — семерых одним ударом!From the Russian cartoon on the German fairy tale.Ilya Muromets is a legendary bogatyr. Right now he is struggling against Zmej Gorynych, a drago…

C# 装箱和拆箱

C#的值类型可以分为在栈上分配内存的值类型和在托管堆上分配内存的引用类型。 1、那么值类型和引用类型能否相互转换呢? 答案是肯定的,C#通过装箱和拆箱来实现两者的相互转换。 (1)、装箱 ---把值类型强制转换成引用类型(object类型) (2)、拆箱 ---把引用类型强制转换成值…

第五章

学会了开发板测试环境的调试和烧写android系统。 学到的知识&#xff1a; 一、安装串口调试工具:minicom 第1步&#xff1a;检测当前系统是否支持USB转串口。 # lsmod | grep usbserial 第2步&#xff1a;安装minicom # qpt-get install minicom 第3步:配置minicom # minicom -…

Angular的后院:组件依赖关系的解决

by Dor Moshe通过Dor Moshe Angular的后院&#xff1a;解决 组件依赖关系 (Angular’s Backyard: The Resolving of Components Dependencies) This article originally appeared on dormoshe.io这篇文章 最初出现在dormoshe.io Many of us use the Hierarchical Dependenc…

node中的Stream-Readable和Writeable解读

在node中&#xff0c;只要涉及到文件IO的场景一般都会涉及到一个类&#xff0d;Stream。Stream是对IO设备的抽象表示&#xff0c;其在JAVA中也有涉及&#xff0c;主要体现在四个类&#xff0d;InputStream、Reader、OutputStream、Writer&#xff0c;其中InputStream和OutputSt…

新Rider预览版发布,对F#的支持是亮点

JetBrains一直在改进自己的跨平台.NET IDE产品Rider&#xff0c;努力使其成为Visual Studio家族产品可承担职能的重要替代者。于今年四月发布的Rider预览版&#xff08;EAP 21&#xff09;提供了一些新特性&#xff0c;其中的亮点在于对函数式编程语言F#的支持。\\鉴于这是Ride…

java代码整合_java合并多个文件的实例代码

在实际项目中&#xff0c;在处理较大的文件时&#xff0c;常常将文件拆分为多个子文件进行处理&#xff0c;最后再合并这些子文件。下面就为各位介绍下Java中合并多个文件的方法。Java中合并子文件最容易想到的就是利用BufferedStream进行读写。具体的实现方式如下&#xff0c;…

正则表达式的一些规则

1.限定修饰符只对其紧前的元字符有效 String rex8 "\\d\\D"; 上式中&#xff0c;只对\\D有效&#xff0c;即有至少有1个&#xff08;1个或多个&#xff09;非数字&#xff0c;\\d仍然只许有一个数字。 2.[1,2,3]和[123]是一样的转载于:https://www.cnblogs.com/Sabr…

2016版单词的减法_在2016年最大的电影中,女性只说了27%的单词。

2016版单词的减法by Amber Thomas通过琥珀托马斯 在2016年最大的电影中&#xff0c;女性只说了27&#xff05;的单词。 (Women only said 27% of the words in 2016’s biggest movies.) Movie trailers in 2016 promised viewers so many strong female characters. Jyn Erso…

软件工程博客---团队项目---个人设计2(算法)

针对分析我们团队项目的需求&#xff0c;我们选定Dijkstra算法。 算法的基本思想&#xff1a; Dijkstra算法是由E.W.Dijkstra于1959年提出&#xff0c;又叫迪杰斯特拉算法&#xff0c;它应用了贪心算法模式&#xff0c;是目前公认的最好的求解最短路径的方法。算法解决的是有向…

UWP 杂记

UWP用选取文件对话框 http://blog.csdn.net/u011033906/article/details/65448394 文件选取器、获取文件属性、写入和读取、保存读取和删除应用数据 https://yq.aliyun.com/articles/839 UWP判断文件是否存在 http://blog.csdn.net/lindexi_gd/article/details/51387901…