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_ID
和CLIENT_ID
創建一個CognitoUserPool
對象,該對象包含大部分Cognito函數。 CognitoUserPool
具有從密碼重置到驗證新用戶的所有功能。 我們在這里創建CognitoUserPool
,這樣我們就不必為每個函數再次實例化它。 我們還設置了USERPOOL_ID
,它是某些Cognito函數所需的URL,由USER_POOL_ID
和region
。 最后,我們還導出了聯邦身份池的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 attrs
。 const 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個屬性: email
, password
和agentName
。 為了將其保存為Cognito用戶的屬性,我們必須為每個用戶創建一個CognitoUserAttribute
對象。 為此,我們創建了一個帶有屬性名稱及其值的dataEmail
和dataAgentName
對象。 這些對象將傳遞到CognitoUserAttribute
函數,該函數將其轉換為AWS Cognito可讀對象,我們將其命名為attributeEmail
和attributeAgentName
。 請注意, 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
函數。 前三個參數是唯一標識符email
, password
和attributeList
數組。 第四個參數為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個基本屬性email
和pin
。 我們創建另一個userData
對象來創建CognitoUser
,以調用confirmRegistration()
函數。 在confirmRegistration()
我們傳入pin
, true
和回調。 如果確認成功,則我們注銷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對象,其中包含用戶email
和password
。 我們還創建了一個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()
接受cognitoUser
和authenticationDetails
參數,并將其用于兩件事。 cognitoUser
有一個名為authenticateUser()
的函數,我們將調用該函數登錄到AWS Cognito。 我們傳入的第一個參數是authenticationDetails
(包含電子郵件和密碼),第二個參數是具有onSuccess
和onFailure
回調的對象。 很簡單, 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