簡體   English   中英

從未認證切換到經過開發人員認證的Cognito用戶-AWS iOS SDK

[英]Switch from unauth to developer authenticated cognito user - AWS iOS SDK

總體問題:在前端(iOS)上使用開發人員身份驗證的身份時遇到問題。 我知道后端會產生正確的令牌和ID,但是我的刷新方法從未被調用過。 我也查看了樣本,但對所發生的一切感到有些困惑。 流程說明:當前,我有一個帶有登錄按鈕的登錄屏幕。 用戶按下登錄按鈕,然后我的api類獲取憑據,加密密碼並將其存儲在鑰匙串中(由於在模擬器上不起作用,目前已注釋掉)。 我的DeveloperAuthenticatedIdentityProvider稱為我的應用程序BusytimeAuthenticated。 我已經完成所有方法(我正在使用AWS lambda和DynamoDB來對用戶進行身份驗證),我從未經身份驗證的訪問開始,這僅允許我訪問兩種方法(登錄和注冊)。 然后,我想假設我的身份驗證用戶允許我調用其他方法。

我的API代碼:

[AWSLogger defaultLogger].logLevel = AWSLogLevelVerbose;
id<AWSCognitoIdentityProvider> identityProvider = [[BusytimeAuthenticated alloc] initWithRegionType:AWSRegionUSEast1
                                                                                                          identityId:nil
                                                                                identityPoolId:@"SOMEIDENTITYPOOLID"
                                                                                logins:@{@"SOMEPROVIDERNAME": @"SOMEUSERNAME"}
                                                                                       providerName:@"SOMEPROVIDERNAME"
                                                                                                          ];

credentialsProvider = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionUSEast1
                                                                    identityProvider:identityProvider
                                                                       unauthRoleArn:nil
                                                                         authRoleArn:nil];

configuration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1
                                                                     credentialsProvider:self.credentialsProvider];
AWSServiceManager.defaultServiceManager.defaultServiceConfiguration = configuration;
[[credentialsProvider refresh] continueWithBlock:^id(BFTask *task){
    [self testAuth];
    return nil;
}];

我的DeveloperAuthenticatedIdentityProvider代碼(BusytimeAuthenticated):

#import "BusytimeAuthenticated.h"

@interface BusytimeAuthenticated()
@property (strong, atomic) NSString *providerName;
@property (strong, atomic) NSString *token;
@end

@implementation BusytimeAuthenticated
@synthesize providerName=_providerName;
@synthesize token=_token;



- (instancetype)initWithRegionType:(AWSRegionType)regionType
                        identityId:(NSString *)identityId
                    identityPoolId:(NSString *)identityPoolId
                            logins:(NSDictionary *)logins
                      providerName:(NSString *)providerName{
    if (self = [super initWithRegionType:regionType identityId:identityId accountId:nil identityPoolId:identityPoolId logins:logins]) {
        self.providerName = providerName;
    }
    return self;
}

// Return the developer provider name which you choose while setting up the
// identity pool in the Amazon Cognito Console

- (BOOL)authenticatedWithProvider {
    return [self.logins objectForKey:self.providerName] != nil;
}


// If the app has a valid identityId return it, otherwise get a valid
// identityId from your backend.

- (BFTask *)getIdentityId {
    // already cached the identity id, return it
    if (self.identityId) {
        return [BFTask taskWithResult:nil];
    }
    // not authenticated with our developer provider
    else if (![self authenticatedWithProvider]) {
        return [super getIdentityId];

    }
    // authenticated with our developer provider, use refresh logic to get id/token pair
    else {
        return [[BFTask taskWithResult:nil] continueWithBlock:^id(BFTask *task) {
            if (!self.identityId) {
                return [self refresh];
            }
            return [BFTask taskWithResult:self.identityId];
        }];
    }

}


// Use the refresh method to communicate with your backend to get an
// identityId and token.

- (BFTask *)refresh {
    if (![self authenticatedWithProvider]) {
        return [super getIdentityId];
    }else{
//        KeychainWrapper *keychain = [[KeychainWrapper alloc]init];
        AWSLambdaInvoker *lambdaInvoker = [AWSLambdaInvoker defaultLambdaInvoker];
        NSDictionary *parameters = @{@"username" : @"SOMEUSERNAME",
                                     @"password":@"SOMEENCRYPTEDPASS",
                                     @"isError" : @NO};
        NSLog(@"Here");
        [[lambdaInvoker invokeFunction:@"login" JSONObject:parameters] continueWithBlock:^id(BFTask* task) {
            if (task.error) {
                NSLog(@"Error: %@", task.error);
            }
            if (task.exception) {
                NSLog(@"Exception: %@", task.exception);
            }
            if (task.result) {
                self.identityId = [task.result objectForKey:@"IdentityId" ];
                self.token = [task.result objectForKey:@"Token" ];
//                [keychain mySetObject:[task.result objectForKey:@"Token" ] forKey:@"Token"];
//                [keychain mySetObject:[task.result objectForKey:@"IdentityId" ] forKey:@"IdentityId"];
                NSLog(@"Result: %@", task.result);

            }
            return [BFTask taskWithResult:self.identityId];
        }];



    }
    return NULL;
}

@end

摘要問題:不幸的是,當我測試新的特權時,我從錯誤中看到:“未授權執行Unauth_Role / CognitoIdentityCredentials:lambda:InvokeFunction”。 顯然,我沒有正確切換。 我在刷新方法中放置了一個斷點,以查看是否被調用。 不是。 我不太了解如何正確切換。 非常感謝您對此工作的任何幫助。

注意:我所做的一大改變是我退出了“ DeveloperAuthenticationClient”類,因為我認為沒有它就可以做到。

根本問題是您正在嘗試調用Lambda函數(需要憑據)以獲取憑據。 因為您使用的是“默認”客戶端配置,所以開發人員通過身份驗證的客戶端返回響應時,它將覆蓋用於訪問Lambda函數的憑據。 此外,一旦該ID轉換為已認證,您將無法使用它獲取未認證流中的憑據,並且需要生成一個新的未經認證的ID才能再次進行認證,然后返回已認證的ID。

我強烈建議您在Lambda函數之前設置API網關 ,以消除這種循環依賴。

根據問題中的新信息進行更新...這里有幾件事情:1.避免使用while(!finished)類的代碼來等待異步任務完成。 在最佳情況下,這種繁忙的等待方式將消耗100%的CPU /內核,而無濟於事,並且對電池壽命產生不利影響,只會損害應用程序的性能。 而是使用帶有塊的通知。 由於您在此實例中已經具有一個AWSTask ,因此不必在[credentialsProvider refresh] continueWithBlock...的結尾處返回nil [credentialsProvider refresh] continueWithBlock...只需在[self testAuth]調用您的[self testAuth][self testAuth]完成的/ while代碼。 2.在您的getIdentityId實現中,第一個if條件檢查是否存在一個identityId,如果存在則返回nil 我猜您的目標是在成功通過身份驗證后緩存identityId並返回該ID,以便您不必在每次調用getIdentityId時都調用后端。 如果是這種情況,請確定您要返回identityId而不是nil 。我不認為這是造成此問題的原因,但可以簡化事情:只要您使用Auth / UnAuth角色配置了身份池在控制台中,初始化AWSCognitoCredentialsProvider時不必顯式使用它們。

如果仍然存在問題,一旦解決了這些問題,請更詳細地調試代碼,並告訴我們以下內容:是否調用了refresh方法? 如果是這樣,則輸入if語句的哪一部分,結果是什么? 它是否曾經進入過else塊並致電您的后端身份提供商? 它是否成功檢索到一個身份ID並將其返回?

如果您走得更遠但開始遇到的問題略有不同,請將該問題標記為已回答,然后發布一個單獨的問題,而不是繼續編輯此問題。 這將有助於使事情保持清晰(此問題/答案越來越長且已更改)。


最初發布的問題/代碼的原始答​​案... AWSCognitoCredentialsProvidergetIdentity方法返回一個AWSTask (即BFTask )。 因此,您需要調用諸如continueWithBlock之類的內容才能實際執行該方法。 在上面的第一段代碼中,您似乎沒有這樣做。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM