当前位置: 首页 > 知识库问答 >
问题:

与AWS开发者身份验证中的登录流逻辑混淆

谯翔
2023-03-14

我相信我有一个不正确的流程来实现开发人员身份验证,我一直在网上听到和做不同的事情。所以我想我应该展示我的整个流程,听听正确的做法是什么,并在底部提出一些问题和错误。

最初,我有一个带有密码和用户名的用户登录(我只是暂时使用nsuserdefaults,稍后我将使用KeyChain)。

注意:我也有一个回调,它会一直向下,以查看我是否正确验证了用户。

登录方式:

-(void)loginBusyTimeUser:(void(^)(BOOL))callBack{
//initialize nsuserdefualts should be keychain later
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

NSMutableDictionary *post = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
                      [defaults objectForKey:@"username"], @"username",
                      [defaults objectForKey:@"password"], @"password",
                      nil];
NSError *error;
NSData *postData = [NSJSONSerialization dataWithJSONObject:post options:0 error:&error];
NSString *postLength = [NSString stringWithFormat:@"%lu", (unsigned long)[postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:@"SOMELOGINURL"]];
[request setHTTPMethod:@"POST"];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setHTTPBody:postData];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
[[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    NSDictionary *newJSON = [NSJSONSerialization JSONObjectWithData:data
                                                            options:0
                                                              error:&error];
    if(!newJSON || [newJSON objectForKey:@"errorMessage"]){
        NSLog(@"%@",newJSON);
        callBack(false);
        NSLog(@"DID NOT AUTHENTICATE");
    }else{
        NSLog(@"%@",newJSON);
        [defaults setValue:[newJSON objectForKey:@"Token"] forKey:@"Token"];
        [defaults setValue:[newJSON objectForKey:@"IdentityId"] forKey:@"IdentityId"];
        [self authenticateUser:^(BOOL call){
            callBack(call);
        }];
    }
}] resume];

}

如果一切都成功,我将使用AWS Cognito和开发者身份验证流对我的用户进行身份验证:

-(void)authenticateUser:(void(^)(BOOL))callBack{
//Now after making sure that your user's credentials are sound, then initialize the IdentityProvider, in this case
//BusytimeAuthenticated
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
id<AWSCognitoIdentityProvider> identityProvider = [[BusytimeAuthenticated alloc] initWithRegionType:AWSRegionUSEast1
                                                                                         identityId:nil
                                                                                     identityPoolId:@"SOMEPOOLID"
                                                                            logins:@{@"cognito-identity.amazonaws.com": [defaults objectForKey:@"Token"]}
                                                                                       providerName:@"cognito-identity.amazonaws.com"
                                                   ];

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(AWSTask *task){
    if([task isFaulted]){
        callBack(false);
    }else{
    callBack(true);
    }
    return [defaults objectForKey:@"Token"];
}];

}

然后刷新方法会导致一些错误,所以我将显示我的BusytimeAuthantated类(. m)

//
//  BusytimeAuthenticated.m
//  BusyTime
//
//  Created by akash kakumani on 10/14/15.
//  Copyright (c) 2015 BusyTime. All rights reserved.
//

#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.

- (AWSTask *)getIdentityId {
    // already cached the identity id, return it
    if (self.identityId) {
        return [AWSTask 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 [[AWSTask taskWithResult:nil] continueWithBlock:^id(AWSTask *task) {
            if (!self.identityId) {
                return [self refresh];
            }
            return [AWSTask taskWithResult:self.identityId];
        }];
    }

}


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

- (AWSTask *)refresh {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    if (![self authenticatedWithProvider]) {
        return [super getIdentityId];
    }else{
        NSDictionary *post = [[NSDictionary alloc] initWithObjectsAndKeys:
                              [defaults objectForKey:@"username"], @"username",
                              [defaults objectForKey:@"password"], @"password",
                              nil];
        NSError *error;
        NSData *postData = [NSJSONSerialization dataWithJSONObject:post options:0 error:&error];
        NSString *postLength = [NSString stringWithFormat:@"%lu", (unsigned long)[postData length]];
        NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
        [request setURL:[NSURL URLWithString:@"SOMELOGINURL"]];
        [request setHTTPMethod:@"POST"];
        [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
        [request setHTTPBody:postData];
        NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
        [[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
            NSDictionary *newJSON = [NSJSONSerialization JSONObjectWithData:data
                                                                    options:0
                                                                      error:&error];
            if(!newJSON){
            NSLog(@"Failure in refresh: %@",newJSON);
            }else{
            NSLog(@"The IdentityID in the refresh method: %@",[newJSON objectForKey:@"IdentityId" ]);
            NSLog(@"The token in the refresh method: %@",[newJSON objectForKey:@"Token" ]);
            self.identityId = [newJSON objectForKey:@"IdentityId" ];
            self.token = [newJSON objectForKey:@"Token" ];
            }
        }] resume];

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


@end

我有一些问题:

>

  • DeveloperAuthenticationClient是否需要解决我的问题?我看到示例应用程序正在使用它们,但我发现它们太令人困惑了。

    我应该使用我的提供商名称还是应该使用“cognito-identity.amazonaws.com”

    我有时会遇到超时错误,并发现可能是我的登录实现(使用API网关lambda方法)存在一些冷启动问题。我解决这个问题的方法是将超时时间增加到20秒。这是解决这个问题的正确方法吗?

    我在示例应用程序中看到,他们使用GetToken和登录作为两个独立的东西。我想如果我的登录名也可以作为我的GetToken,那会更容易。这是否恰当?

    最后,如果时间允许,请解决您在我的代码中看到的任何问题。

    错误:

    [错误]AWSCredentialsProvider.m行:527 |(UU 40-[AWSCognitoRedentialsProvider刷新](U块)调用352 |无法刷新。错误为[Error Domain=com.amazonaws.AWSCognitoCredentialsProviderErrorDomain Code=1“identityId不应为nil”UserInfo={NSLocalizedDescription=identityId不应为nil}]

    (我还发现上述错误与未设置self.identityId有关,因为请求位于块中,其他部分先执行,解决方案是:

    - (AWSTask *)refresh {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    if (![self authenticatedWithProvider]) {
        return [super getIdentityId];
    }else{
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        NSString *string = [defaults objectForKey:@"IdentityId"];
        self.identityId = string;
        return [AWSTask taskWithResult:[defaults objectForKey:@"IdentityId"]];
    }
    NSString *string = [defaults objectForKey:@"IdentityId"];
    return [AWSTask taskWithResult:[defaults objectForKey:@"IdentityId"]];
    }
    

    但我认为这不是正确的实现。)

    我相信我的代码在某一点上可以工作,但在升级到新的SDK后就停止了工作。然而,这可能只是因为我最初没有注意到错误。

  • 共有1个答案

    汤飞羽
    2023-03-14

    回答您的问题:

    >

    您正在登录映射中使用cognito-identity.amazonaws.com,但使用IdentityProvider模式进行刷新。这就是第一次身份验证成功但尝试刷新失败的原因。刷新中的逻辑永远不会触发。请看我们关于如何实现开发人员身份验证的端到端示例

    据我所知,这是一种方法,但您可能会面临性能问题。请通过论坛联系AWS Lambda,以获取更多相关指导。

    我们强烈建议遵循样本中的流程。如果您已经建立了信任,则getToken不需要您的身份验证凭据,而登录将始终需要身份验证凭据,因此最好不要混合使用这些凭据。

    谢谢...

     类似资料:
    • 本文向大家介绍详解Angular开发中的登陆与身份验证,包括了详解Angular开发中的登陆与身份验证的使用技巧和注意事项,需要的朋友参考一下 前言 由于 Angular 是单页应用,会在一开始,就把大部分的资源加载到浏览器中,所以就更需要注意验证的时机,并保证只有通过了验证的用户才能看到对应的界面。 本篇文章中的身份验证,指的是如何确定用户是否已经登陆,并确保在每次与服务器的通信中,都能够满足服

    • 使用,https://github.com/firebase/FirebaseUI-Android/tree/master/codelabs/chat作为登录的参考,我在键入时似乎遇到了问题 我只能键入Auth的提供者,而不能键入,为什么会这样,它提示我键入社会提供者。

    • 当使用Firebase身份验证匿名帐户时,它偶尔会在系统中创建一个新的用户ID,有时它会使用相同的用户ID。我真的希望每次都能创建相同的用户ID,这样匿名用户仍然可以在应用程序中维护相同的进度/数据。这实际上是我开始使用Firebase的原因。即使在重新启动应用程序等之后,我如何始终维护一个匿名帐户来保持相同的用户ID? 我希望用户每次以访客身份玩游戏时都能获得相同的ID。我看到有些应用程序在卸载

    • 我们有一个现有的JavaEE应用程序在WebLogic下运行,我想以编程方式对用户进行身份验证,就像用户是通过现有的web登录过程登录的一样。也就是说,最后,我希望有一个有效的会话(cookie),可以返回给调用者,然后返回给服务器,而无需重新身份验证。(这是为了启用JAX-WS有状态Web服务调用)。 我们有一个定制的LoginModule,当用户通过表单身份验证登录时,最终会通过j_secur

    • 本文向大家介绍asp.net mvc中Forms身份验证身份验证流程,包括了asp.net mvc中Forms身份验证身份验证流程的使用技巧和注意事项,需要的朋友参考一下 验证流程 一、用户登录 1、验证表单:ModelState.IsValid 2、验证用户名和密码:通过查询数据库验证 3、如果用户名和密码正确,则在客户端保存Cookie以保存用户登录状态:SetAuthCookie     1