AWS Cognito - 如何更新开发者经过身份验证的用户令牌?

时间:2015-12-14 12:35:06

标签: ios amazon-web-services amazon-cognito

在我的应用程序中,所有用户都从Cognito的identityId开始(直接从应用程序中获取Cognito / GetId),经过身份验证的用户通过开发人员身份验证更新identityId(GetOpenIdTokenForDeveloperIdentity使用通过开发人员服务器设置的旧IdentityId)。 经过身份验证的用户可以随时注销/登录,但一旦注销或令牌过期,开发人员端令牌就会更改。

在上述条件下,为用户设置相同的identityId的最佳方法是什么?

例如:当同一个用户注销时,然后登录。

  1. 用户首次运行该应用。他将 IdentityA 作为未经身份验证的identityId,登录为空。他在 DatasetA 上保存了一些数据。
  2. 用户使用USER / PASSWORD登录。他登录{" DEVDOMAIN":" TokenA "}作为登录信息。 GetOpenIdTokenForDeveloperIdentity( IdentityA ,DEVDOMAIN: TokenA )链接它们,用户通过 IdentityA 进行身份验证,并保留 DatasetA
  3. 用户退出。他得到未经身份验证的 IdentityB ,登录/数据集为空。他在 DatasetB 上保存了一些数据。
  4. 用户使用USER / PASSWORD登录。他登录{" DEVDOMAIN":" TokenB "}作为登录信息。
  5. 在这种情况下我需要的是与该用户相关联:

    • 最新令牌令牌B
    • 以同一用户身份访问AWS的IdentityId。
    • 数据集B 合并到数据集

    调用GetOpenIdTokenForDeveloperIdentity( IdentityB ,DEVDOMAIN: TokenB )是否意味着创建新用户权限? 我也应该......

    1. 在开发者端数据库中保存当前在Cognito上注册的用户令牌( tokenA )以及不会更改的第一个identityId( identityA
    2. 调用GetOpenIdTokenForDeveloperIdentity( IdentityB ,DEVDOMAIN: TokenB )暂时关联 IdentityB TokenB
    3. 然后调用MergeDeveloperIdentities( TokenB TokenA )(我希望这会合并数据集......)
    4. 也许会调用DeleteIdentities( IdentityB ),因为它永远不会被使用?
    5. 然后告诉应用程序"您 IdentityA "
    6. 有更好的方法吗?

      感谢。

      编辑:

      TokenA / TokenB 是开发者端服务器API的访问令牌。 它们每次用户登录时都会更改,它们会在2周后过期。

      我用于注销的代码:

      // Code in Logout
      AWSCognitoCredentialsProvider* credentialsProvider = [AWSServiceManager defaultServiceManager].defaultServiceConfiguration.credentialsProvider;
      [credentialsProvider clearKeychain];
      [[AWSCognito defaultCognito] wipe];
      

      登录/退出后,我会以这种方式更新用户的身份:

      AWSCognitoCredentialsProvider* credentialsProvider = [AWSServiceManager defaultServiceManager].defaultServiceConfiguration.credentialsProvider;
      
      NSString* previousIdToken = credentialsProvider.logins[IDPROVIDER_OURSERVICE];
      if (previousIdToken == nil || ![idToken isEqualToString:previousIdToken])
      {
          if (idToken.length == 0)
          {
              // Logout
              credentialsProvider.logins = @{ };
              return [credentialsProvider getIdentityId];
          }
          else
          {
              // Login/Update
              credentialsProvider.logins = @{ IDPROVIDER_OURSERVICE:idToken };
              return [credentialsProvider refresh];
          }
      }
      
      return [AWSTask taskWithResult:idToken];
      

      我还在启动时运行以下代码,以便在用户重新安装应用时清除凭据(在我的应用中卸载=注销)

      // Initialization code
      AppIdentityProvider* appIdentityProvider = [[AppIdentityProvider alloc] initWithRegionType:AWSRegionUSEast1
                                                                                      identityId:nil
                                                                                       accountId:COGNITO_ACOUNT_ID
                                                                                  identityPoolId:COGNITO_IDENTITY_POOL_ID
                                                                                          logins:logins];
      AWSCognitoCredentialsProvider* credentialsProvider = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionUSEast1
                                                                                                    identityProvider:appIdentityProvider
                                                                                                       unauthRoleArn:nil
                                                                                                         authRoleArn:nil];
      
      if ([AppContext sharedInstance].appInitRunCount == 1)
      {
          // Restart as guest after an uninstall
          NSLog(@"=== AppUserManager: First run: clearing keychain");
          [[AWSCognito defaultCognito] wipe];
          [credentialsProvider clearKeychain];
      }
      
      AWSServiceConfiguration* configuration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1
                                                                           credentialsProvider:credentialsProvider];
      [AWSServiceManager defaultServiceManager].defaultServiceConfiguration = configuration;
      
      [[credentialsProvider getIdentityId] continueWithSuccessBlock:^id(AWSTask *task) {
          [self testCognito];
          return nil;
      }];
      

      我的自定义身份提供商如下所示:

      @interface AppIdentityProvider : AWSAbstractCognitoIdentityProvider
      // ...
      @end
      
      @interface AppIdentityProvider ()
      @property (nonatomic, strong, readwrite) NSString *token;
      @end
      
      @implementation AppIdentityProvider
      
      @synthesize token = _token;
      
      -(id)initWithRegionType:(AWSRegionType)regionType
                   identityId:(NSString*)identityId
                    accountId:(NSString*)accountId
               identityPoolId:(NSString*)identityPoolId
                       logins:(NSDictionary*)logins
      {
          self = [super initWithRegionType:regionType
                                identityId:identityId
                                 accountId:accountId
                            identityPoolId:identityPoolId
                                    logins:logins];
          if (self == nil)
              return nil;
      
          return self;
      }
      
      -(BOOL)isAuthenticatedWithOurService
      {
        return self.logins != nil && [self.logins objectForKey:IDPROVIDER_OURSERVICE] != nil;
      }
      
      - (AWSTask *)getIdentityId
      {
          if (self.identityId != nil)
              return [AWSTask taskWithResult:self.identityId];
          if (![self isAuthenticatedWithOurService])
              return [super getIdentityId];
          return [[AWSTask taskWithResult:nil] continueWithBlock:^id(AWSTask *task) {
              if (self.identityId != nil)
                  return [AWSTask taskWithResult:self.identityId];
              return [self refresh];
          }];
      }
      
      - (AWSTask *)refresh
      {
          AWSTaskCompletionSource *source = [AWSTaskCompletionSource taskCompletionSource];
          if (![self isAuthenticatedWithOurService])
              return [super getIdentityId];
          ApiRequest* authApi = [[ApiRequestManager sharedInstance] generateAuthApiByIdToken:self.logins[IDPROVIDER_OURSERVICE]];
          [authApi requestAsyncCompletionHandler:^(ApiRequest *request)
           {
               NSDictionary *response = request.response;
      
               if ([request hasSucceeded] && [[response valueForKey:@"result"] intValue] == 1)
               {
                   self.token = [[response valueForKey:@"data"] valueForKey:@"token"];
                   self.identityId = [[response valueForKey:@"data"] valueForKey:@"identityId"];
                   [source setResult:self.identityId];
               }
               else
               {
                   [source setError:[NSError errorWithDomain:@"refresh" code:0 userInfo:response]];
               }
           }];
      
          return source.task;
      }
      
      @end
      

1 个答案:

答案 0 :(得分:1)

如果您希望用户始终拥有相同的身份ID,则不应使用随机生成的令牌作为用户标识符进行更改。我们根据您传递给我们的标识符唯一地标识用户。例如,当您从后端调用GetOpenIdTokenForDeveloperIdentity时,可以在登录映射中使用用户名。

如果我们已经为标识符生成了一个标识,并且该标识与您在请求中传递的标识不匹配,我们会将这两个标识与其数据集合并。

有关开发人员身份验证流程的更多详细信息,请参阅our dev guide