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



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

在上述条件下,管理用户保持相同identityId的最佳方法是什么?

例如:当同一用户注销后再登录。

  1. 用户第一次运行应用程序。他得到IdentityA作为未经身份验证的identityId,登录为空。他将一些数据保存在DatasetA
  2. 用户使用user/PASSWORD登录。他获得{"DEVDOMAIN":"TokenA"}作为登录名。GetOpenIdTokenForDeveloperIdentity(IdentityA,DEVDOMAIN:TokenAdentityA进行身份验证,并保留数据集A
  3. 用户注销。他未经身份验证IdentityB,登录名/数据集为空。他将一些数据保存在数据集B
  4. 用户使用user/PASSWORD登录。他获得{"DEVDOMAIN":"TokenB"}作为登录名

在这种情况下,我需要的是与这个用户关联:

  • 最新的令牌TokenB
  • 以同一用户身份访问AWS的IdentityId
  • DatasetB合并到DatasetA

调用GetOpenIdTokenForDeveloperIdentity(IdentityB,DEVDOMAIN:TokenB

  1. 在开发人员端数据库中保存当前在Cognito上注册的用户令牌(tokenA)和不会更改的第一个identityId(identityA
  2. 调用GetOpenIdTokenForDeveloperIdentity
  3. 然后调用MergeDeveloperIdentities(TokenBTokenA)(我希望这将合并数据集…)
  4. 也许调用DeleteIdentities(IdentityB),因为它永远不会被使用
  5. 然后告诉应用程序"您是IdentityA"

有更好的方法吗?

谢谢。

编辑:

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

我用于注销的代码:

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

登录/注销后,我以这种方式更新用户的identityId:

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

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

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

有关开发人员身份验证流的更多详细信息,请参阅我们的开发指南。

最新更新