Amazon Cognito
开发人员指南
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

示例:将用户池与 iOS 开发工具包结合使用

本主题将详细介绍在将用户池与AWS Mobile SDK for iOS结合使用时,如何注册、确认和验证用户以及获取用户属性。

创建 AWSCognitoIdentityUserPool 对象

以下过程介绍如何创建要与之进行交互的 AWSCognitoIdentityUserPool 对象。

  1. 设置服务配置。

    注意

    credentialsProvider 设置为 nil。您不需要凭证提供商或 AWS 凭证来与该服务交互。

    //setup service config AWSServiceConfiguration *serviceConfiguration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1 credentialsProvider:nil];
  2. 创建用户池配置。

    //create a pool AWSCognitoIdentityUserPoolConfiguration *configuration = [[AWSCognitoIdentityUserPoolConfiguration alloc] initWithClientId:@"CLIENT_ID" clientSecret:@"CLIENT_SECRET" poolId:@"USER_POOL_ID"]; [AWSCognitoIdentityUserPool registerCognitoIdentityUserPoolWithConfiguration:serviceConfiguration userPoolConfiguration:configuration forKey:@"UserPool"]; AWSCognitoIdentityUserPool *pool = [AWSCognitoIdentityUserPool CognitoIdentityUserPoolForKey:@"UserPool"];

示例:注册用户

使用 pool.signUp:password:userAttributes:validationData 注册用户。

AWSCognitoIdentityUserAttributeType * phone = [AWSCognitoIdentityUserAttributeType new]; phone.name = @"phone_number"; //phone number must be prefixed by country code phone.value = @"+15555555555"; AWSCognitoIdentityUserAttributeType * email = [AWSCognitoIdentityUserAttributeType new]; email.name = @"email"; email.value = @"email@mydomain.com"; //sign up the user [[pool signUp:@"username" password:@"password" userAttributes:@[email,phone] validationData:nil] continueWithBlock:^id _Nullable(AWSTask<AWSCognitoIdentityUserPoolSignUpResponse *> * _Nonnull task) { dispatch_async(dispatch_get_main_queue(), ^{ if(task.error){ [[[UIAlertView alloc] initWithTitle:task.error.userInfo[@"__type"] message:task.error.userInfo[@"message"] delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil] show]; }else { AWSCognitoIdentityUserPoolSignUpResponse * response = task.result; if(!response.userConfirmed){ //need to confirm user using user.confirmUser: } }}); return nil; }];

示例:获取用户

您可以通过注册或在池中使用以下方法之一来获取用户。

//get the last logged in user [pool currentUser]; //get a user without a username [pool getUser]; //get a user with a specific username [pool getUser:@"username"];

示例:登录用户

有两种登录方法:显式登录或通过委托(当需要用户凭证时)。

要进行显式登录,请使用以下命令:

[[user getSession:@"username" password:@"password" validationData:nil scopes:nil] continueWithSuccessBlock:^id _Nullable(AWSTask<AWSCognitoIdentityUserSession *> * _Nonnull task) { //success, task.result has user session return nil; }];

要实施委托,请实施 AWSCognitoIdentityInteractiveAuthenticationDelegate 并在池中设置委托:

pool.delegate = self;

在实施过程中,写入代码以实例化您的身份验证用户界面 (如未创建) 并进行显示。

//set up password authentication ui to retrieve username and password from the user -(id) startPasswordAuthentication { //write code to instantiate your sign in ui if it wasn't created here dispatch_async(dispatch_get_main_queue(), ^{ //write code to display your ui }); //return your sign in ui which implements the AWSCognitoIdentityPasswordAuthentication protocol return signInViewController; } //set up mfa ui to retrieve mfa code from end user //this is optional and only necessary if you turn on multifactor authentication on your pool -(id) startMultiFactorAuthentication { //write code to instantiate your multifactor authentication ui if it wasn’t created here dispatch_async(dispatch_get_main_queue(), ^{ //write code to display your ui }); //return your sign in ui which implements the AWSCognitoIdentityMultiFactorAuthentication protocol return mfaViewController; } //set up new password required ui to retrieve new password and any required user profile from end user //this is optional and only necessary if you use the AdminCreateUser feature on the pool -(id) startNewPasswordRequired { //write code to instantiate your new password required ui if it wasn’t created here dispatch_async(dispatch_get_main_queue(), ^{ //write code to display your ui }); //return your new password required ui which implements the AWSCognitoIdentityNewPasswordRequired protocol return newPasswordRequiredController; } //set up ui to prompt end user to setup a software MFA //this is optional and only necessary if you have software MFA enabled and MFA is required on your pool -(id<AWSCognitoIdentitySoftwareMfaSetupRequired>) startSoftwareMfaSetupRequired { //write code to instantiate your software token setup required ui if it wasn’t created here dispatch_async(dispatch_get_main_queue(), ^{ //write code to display your ui }); //return your software mfa setup required ui which implements the AWSCognitoIdentitySoftwareMfaSetupRequired protocol return softwareMfaSetupController; } //set up ui to prompt end user to select which MFA they want for this authentication //this is optional and only necessary if you have users can have multiple MFAs setup on the pool -(id<AWSCognitoIdentitySelectMfa>) startSelectMfa { //write code to instantiate your select MFA ui if it wasn’t created here dispatch_async(dispatch_get_main_queue(), ^{ //write code to display your ui }); //return your select MFA ui which implements the AWSCognitoIdentitySelectMfa protocol return selectMfaController; } //set up ui to drive a custom authentication flow //this is optional and only necessary if you have custom authentication lambdas configured on your pool -(id<AWSCognitoIdentityCustomAuthentication>) startCustomAuthentication { //write code to instantiate your custom authentication ui if it wasn’t created here dispatch_async(dispatch_get_main_queue(), ^{ //write code to display your ui }); //return your custom authentication ui which implements the AWSCognitoIdentityCustomAuthentication protocol return customAuthenticationController; }

在密码身份验证 UI 中,实施 AWSCognitoIdentityPasswordAuthentication 协议。

-(void) getPasswordAuthenticationDetails: (AWSCognitoIdentityPasswordAuthenticationInput *) authenticationInput passwordAuthenticationCompletionSource: (AWSTaskCompletionSource<AWSCognitoIdentityPasswordAuthenticationDetails *> *) passwordAuthenticationCompletionSource { //keep a handle to the completion, you'll need it continue once you get the inputs from the end user self.passwordAuthenticationCompletion = passwordAuthenticationCompletionSource; //authenticationInput has details about the last known username if you need to use it } -(void) didCompletePasswordAuthenticationStepWithError:(NSError*) error { dispatch_async(dispatch_get_main_queue(), ^{ //on completion, either display the error or dismiss the ui if(error){ [[[UIAlertView alloc] initWithTitle:error.userInfo[@"__type"] message:error.userInfo[@"message"] delegate:nil cancelButtonTitle:nil otherButtonTitles:@"Retry", nil] show]; }else{ [self dismissViewControllerAnimated:YES completion:nil]; } }); }

当最终用户输入其用户名称和密码时,设置 passwordAuthenticationCompletion 结果。

self.passwordAuthenticationCompletion.result = [[AWSCognitoIdentityPasswordAuthenticationDetails alloc] initWithUsername:@"username" password:@"password"];

如果您支持多重验证 (MFA),则可以实施 AWSCognitoIdentityMultiFactorAuthentication 协议。

-(void) getMultiFactorAuthenticationCode: (AWSCognitoIdentityMultifactorAuthenticationInput )authenticationInput mfaCodeCompletionSource: (AWSTaskCompletionSource<NSString > *) mfaCodeCompletionSource { //keep a handle to the completion, you’ll need it continue once you get the inputs from the end user self.mfaCodeCompletion = mfaCodeCompletionSource; //authenticationInput has details about where the mfa code was sent if you need to display them in your ui } -(void) didCompleteMultifactorAuthenticationStepWithError:(NSError*) error { dispatch_async(dispatch_get_main_queue(), ^{ //on completion, either display the error or dismiss the ui if(error){ [[[UIAlertView alloc] initWithTitle:error.userInfo[@"__type"] message:error.userInfo[@"message"] delegate:nil cancelButtonTitle:nil otherButtonTitles:@"Retry", nil] show]; }else{ [self dismissViewControllerAnimated:YES completion:nil]; }}); }

当最终用户输入其代码时,设置 mfaCodeCompletion 结果。

self.mfaCodeCompletion.result = @"mfaCodeFromUser";

如果您支持使用 AdminCreateUser 进行注册,则可以实施 AWSCognitoIdentityNewPasswordRequired 协议。

-(void) getNewPasswordDetails: (AWSCognitoIdentityNewPasswordRequiredInput *) newPasswordRequiredInput newPasswordRequiredCompletionSource:(AWSTaskCompletionSource<AWSCognitoIdentityNewPasswordRequiredDetails *> *) newPasswordRequiredCompletionSource { //keep a handle to the completion, you’ll need it continue once you get the inputs from the end user self.newPasswordRequiredCompletionSource = newPasswordRequiredCompletionSource; //newPasswordRequiredInput has details about the existing user attributes and required fields if you need to display them in your ui } -(void) didCompleteNewPasswordStepWithError:(NSError* _Nullable) error { dispatch_async(dispatch_get_main_queue(), ^{ //on completion, either display the error or dismiss the ui if(error){ [[[UIAlertView alloc] initWithTitle:error.userInfo[@"__type"] message:error.userInfo[@"message"] delegate:nil cancelButtonTitle:nil otherButtonTitles:@"Retry", nil] show]; }else{ [self dismissViewControllerAnimated:YES completion:nil]; }});

当最终用户输入其建议密码和任何所需的属性时,设置 newPasswordRequiredCompletionSource 结果。

NSDictionary<NSString *, NSString *> *userAttributes = @{@"name":@"My new name", @"email":@"mynewemail@myemail.com"}; AWSCognitoIdentityNewPasswordRequiredDetails *details = [[AWSCognitoIdentityNewPasswordRequiredDetails alloc] initWithProposedPassword:@"newPassword" userAttributes:userAttributes]; self.newPasswordRequiredCompletionSource.result = details;

如果支持软件 MFA,则您可以实施 AWSCognitoIdentitySoftwareMfaSetupRequired 协议。

-(void) getSoftwareMfaSetupDetails: (AWSCognitoIdentitySoftwareMfaSetupRequiredInput *) softwareMfaSetupInput softwareMfaSetupRequiredDetails: (AWSTaskCompletionSource<AWSCognitoIdentitySoftwareMfaSetupRequiredDetails *> *) softwareMfaSetupRequiredCompletionSource{ //keep a handle to the completion, you’ll need it continue once you get the inputs from the end user self.softwareMfaSetupRequiredCompletionSource = softwareMfaSetupRequiredCompletionSource; // softwareMfaSetupInput has details about the secret code the end user needs to register with their TOTP application. } -(void) didCompleteMfaSetupStepWithError:(NSError* _Nullable) error { dispatch_async(dispatch_get_main_queue(), ^{ //on completion, either display the error or dismiss the ui if(error){ [[[UIAlertView alloc] initWithTitle:error.userInfo[@"__type"] message:error.userInfo[@"message"] delegate:nil cancelButtonTitle:nil otherButtonTitles:@"Retry", nil] show]; }else{ [self dismissViewControllerAnimated:YES completion:nil]; } }); }

当最终用户从他们的软件令牌应用程序中得到当前代码时,在 softwareMfaSetupRequiredCompletionSource 上设置结果。

AWSCognitoIdentitySoftwareMfaSetupRequiredDetails *details = [[AWSCognitoIdentitySoftwareMfaSetupRequiredDetails alloc] initWithUserCode: @"User Code" friendlyDeviceName:@"Friendly Name" ]; self.newPasswordRequiredCompletionSource.result = details;

如果支持多个 MFA 类型,则可以实施 AWSCognitoIdentitySelectMfa 协议。

-(void) getSelectMfaDetails: (AWSCognitoIdentitySelectMfaInput *) selectMfaInput selectMfaCompletionSource: (AWSTaskCompletionSource<AWSCognitoIdentitySelectMfaDetails *> *) selectMfaCompletionSource { //keep a handle to the completion, you’ll need it continue once you get the inputs from the end user self.selectMfaCompletionSource = selectMfaCompletionSource; // selectMfaInput has details about what MFAS are available to select. } -(void) didCompleteMfaSetupStepWithError:(NSError* _Nullable) error { dispatch_async(dispatch_get_main_queue(), ^{ //on completion, either display the error or dismiss the ui if(error){ [[[UIAlertView alloc] initWithTitle:error.userInfo[@"__type"] message:error.userInfo[@"message"] delegate:nil cancelButtonTitle:nil otherButtonTitles:@"Retry", nil] show]; }else{ [self dismissViewControllerAnimated:YES completion:nil]; } }); }

当最终用户选择了 MFA 时,在 selectMfaCompletionSource 上设置结果。

AWSCognitoIdentitySoftwareMfaSetupRequiredDetails *details = [[AWSCognitoIdentitySelectMfaDetails alloc] initWithSelectedMfa: @"Selected MFA" ]; self.selectMfaCompletionSource.result = details;

示例:忘记密码

[[user forgotPassword] continueWithSuccessBlock:^id _Nullable(AWSTask<AWSCognitoIdentityUserForgotPasswordResponse*> * _Nonnull task) { //success return nil; }]; [[user confirmForgotPassword:@"code" password:@"newPassword"] continueWithSuccessBlock:^id _Nullable(AWSTask<AWSCognitoIdentityUserConfirmForgotPasswordResponse *> * _Nonnull task) { //success return nil; }];

示例:Amazon Pinpoint 分析

以下过程介绍如何在您的 iOS Amazon Cognito 应用程序中集成 Amazon Pinpoint。

  1. 登录 AWS 管理控制台并通过以下网址打开 Amazon Pinpoint 控制台:https://console.amazonaws.cn/pinpoint/

  2. 创建 Amazon Pinpoint 应用程序。记下 Amazon Pinpoint 应用程序 ID。

  3. 在您的 Amazon Cognito 应用程序中,当您实例化 Amazon Cognito 用户池实例时,请提供 AWSCognitoIdentityUserPoolConfiguration 并使用上一步中的 Amazon Pinpoint 应用程序 ID 来设置 pinpointAppId

    Objective-C:

    AWSCognitoIdentityUserPoolConfiguration * poolConfiguration = [[AWSCognitoIdentityUserPoolConfiguration alloc] initWithClientId:@"YOUR_APP_CLIENT_ID" clientSecret:@"YOUR_OPTIONAL_APP_CLIENT_SECRET" poolId:@"YOUR_USER_POOL_ID" shouldProvideCognitoValidationData:YES pinpointAppId:@"YOUR_PINPOINT_APP_ID"];

    Swift:

    let poolConfiguration = AWSCognitoIdentityUserPoolConfiguration(clientId: "YOUR_APP_CLIENT_ID", clientSecret: "YOUR_OPTIONAL_APP_CLIENT_SECRET", poolId: "YOUR_USER_POOL_ID", shouldProviderCognitoValidationData: YES, pinpointAppId: "YOUR_PINPOINT_APP_ID")

经过身份验证的示例:获取用户属性

[[user getDetails] continueWithBlock:^id _Nullable(AWSTask<AWSCognitoIdentityUserGetDetailsResponse *> * _Nonnull task) { dispatch_async(dispatch_get_main_queue(), ^{ if(task.error){ [[[UIAlertView alloc] initWithTitle:task.error.userInfo[@"__type"] message:task.error.userInfo[@"message"] delegate:self cancelButtonTitle:nil otherButtonTitles:@"Retry", nil] show]; }else{ AWSCognitoIdentityUserGetDetailsResponse *response = task.result; //do something with response.userAttributes } }); return nil; }];

经过身份验证的示例:验证用户属性

[[user getAttributeVerificationCode:@"phone_number"] continueWithSuccessBlock:^id _Nullable(AWSTask<AWSCognitoIdentityUserGetAttributeVerificationCodeResponse *> * _Nonnull task) { //success return nil; }]; [[user verifyAttribute:@"phone_number"code:@"code"] continueWithSuccessBlock:^id _Nullable(AWSTask<AWSCognitoIdentityUserVerifyAttributeResponse *> * _Nonnull task) { //success return nil; }];

经过身份验证的示例:更新用户属性

AWSCognitoIdentityUserAttributeType * attribute = [AWSCognitoIdentityUserAttributeType new]; attribute.name = @"name"; attribute.value = @"John User"; [[user updateAttributes:@[attribute]] continueWithSuccessBlock:^id _Nullable(AWSTask<AWSCognitoIdentityUserUpdateAttributesResponse *> * _Nonnull task) { //success return nil; }];

经过身份验证的示例:更改密码

[[user changePassword:@"currentPassword" proposedPassword:@"proposedPassword"] continueWithSuccessBlock:^id _Nullable(AWSTask<AWSCognitoIdentityUserChangePasswordResponse *> * _Nonnull task) { //success return nil; }];

经过身份验证的示例:启用 SMS MFA

AWSCognitoIdentityUserSettings * settings = [AWSCognitoIdentityUserSettings new]; AWSCognitoIdentityUserMFAOption * mfaOptions = [AWSCognitoIdentityUserMFAOption new]; mfaOptions.attributeName = @"phone_number"; mfaOptions.deliveryMedium = AWSCognitoIdentityProviderDeliveryMediumTypeSms; settings.mfaOptions = @[mfaOptions]; [[user setUserSettings:settings] continueWithSuccessBlock:^id _Nullable(AWSTask<AWSCognitoIdentityUserSetUserSettingsResponse *> * _Nonnull task) { //success return nil; }];

经过身份验证的示例:启用软件 MFA

//start by calling associateSoftwareToken to get a secret code for end user to register [[self.user associateSoftwareToken] continueWithSuccessBlock:^id _Nullable(AWSTask<AWSCognitoIdentityUserAssociateSoftwareTokenResponse *> * _Nonnull t) { dispatch_async(dispatch_get_main_queue(), ^{ UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Associate Software MFA" message:t.result.secretCode preferredStyle:UIAlertControllerStyleAlert]; [alert addAction:[UIAlertAction actionWithTitle:@"Verify" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { //verify the software token by having end user input current code [[self.user verifySoftwareToken:alert.textFields[0].text friendlyDeviceName: @"My Software Token"] continueWithSuccessBlock:^id _Nullable(AWSTask<AWSCognitoIdentityUserVerifySoftwareTokenResponse *> * _Nonnull t) { //now the software token is configured, but not enabled, enable it AWSCognitoIdentityUserMfaPreferences * mfaPreferences = [AWSCognitoIdentityUserMfaPreferences new]; mfaPreferences.softwareTokenMfa = [[AWSCognitoIdentityUserMfaType alloc] initWithEnabled:YES preferred:NO]; [[self.user setUserMfaPreference:mfaPreferences] continueWithSuccessBlock:^id _Nullable(AWSTask<AWSCognitoIdentityUserSetUserMfaPreferenceResponse *> * _Nonnull t) { return t; }]; return nil; }]; }]]; [alert addTextFieldWithConfigurationHandler:^(UITextField *textField) { textField.placeholder = @"User Code:"; }]; [self presentViewController:alert animated:YES completion:nil]; }); return nil; }];