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.pswp.cn/news/395830.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/395830.shtml
英文地址,請注明出處:http://en.pswp.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…