gpt4 book ai didi

ios - API Gateway 为授权用户生成带有 Cognito 用户池的 iOS SDK (Objective-C)

转载 作者:行者123 更新时间:2023-12-01 15:58:29 28 4
gpt4 key购买 nike

我已经使用 AWS API Gateway 部署了一个 API,我正在尝试通过 iOS 设备访问它。一些端点支持未经授权的用户,我可以轻松访问它们,但其他端点不支持,我无法查询它们。我使用新的 Cognito 用户池功能进行身份验证,在使用 Web 应用程序(或 postman )时效果很好。

首先,即使某些端点受到保护(如下面的控制台图片),当我部署 API 并生成适用于 iOS(Objective-C)的 SDK 时,我可以在 README 文件中读取:“所有端点都可以不需要授权。”

enter image description here

然后,当我从 AWS 文档运行以下身份验证代码时,一切似乎都运行良好:

AWSServiceConfiguration *serviceConfiguration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionEUWest1 credentialsProvider:nil];
AWSCognitoIdentityUserPoolConfiguration *userPoolConfiguration = [[AWSCognitoIdentityUserPoolConfiguration alloc] initWithClientId:ClientId clientSecret:nil poolId:UserPoolId];
[AWSCognitoIdentityUserPool registerCognitoIdentityUserPoolWithConfiguration:serviceConfiguration userPoolConfiguration:userPoolConfiguration forKey:@"UserPool"];
AWSCognitoIdentityUserPool *pool = [AWSCognitoIdentityUserPool CognitoIdentityUserPoolForKey:@"UserPool"];

AWSCognitoIdentityUser *user = [pool getUser];
[[user getSession:username password:password validationData:nil] continueWithBlock:^id(AWSTask<AWSCognitoIdentityUserSession *> *task) {
if (task.error) {
NSLog(@"Could not get user session. Error: %@", task.error);
} else if (task.exception) {
NSLog(@"Could not get user session. Exception: %@", task.exception);
} else {
NSLog(@"Successfully retrieved user session data");
AWSCognitoIdentityUserSession *session = (AWSCognitoIdentityUserSession *) task.result;

NSMutableString *poolId = [[NSMutableString alloc] initWithString:@"cognito-idp.eu-west-1.amazonaws.com/"];
[poolId appendString:UserPoolId];
NSString *tokenStr = [session.idToken tokenString];
NSDictionary *tokens = [[NSDictionary alloc] initWithObjectsAndKeys:tokenStr, poolId, nil];



CognitoPoolIdentityProvider *idProvider = [[CognitoPoolIdentityProvider alloc] init];
[idProvider addTokens:tokens];

AWSCognitoCredentialsProvider *credentialsProvider = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionEUWest1 identityPoolId:IdentityPoolId identityProviderManager:idProvider];

[credentialsProvider clearKeychain];
[credentialsProvider clearCredentials];

AWSServiceManager.defaultServiceManager.defaultServiceConfiguration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionEUWest1
credentialsProvider:credentialsProvider];

[[credentialsProvider getIdentityId] continueWithBlock:^id _Nullable(AWSTask<NSString *> * _Nonnull task) {
if (task.error) {
NSLog(@"Could not get identity id: %@", task.error);
} else if (task.exception) {
NSLog(@"Could not get identity id: %@", task.exception);
} else {
NSLog(@"Identity id: %@", task.result);
}

return nil;
}];
}

return nil;
}];

我实现了 this post 中指定的 CognitoPoolIdentityProvider .
@interface CognitoPoolIdentityProvider ()
@property (strong, nonatomic) NSDictionary *tokens;
@end

@implementation CognitoPoolIdentityProvider

- (AWSTask<NSDictionary *> *)logins {
return [AWSTask taskWithResult:self.tokens];
}

- (void)addTokens:(NSDictionary *)tokens {
self.tokens = tokens;
}

@end

我设法获得了一个正确的 token (使用 postman 测试)和一个用户 ID:

2016-12-27 12:43:35.760 AskHub[26625:10037234] AWSiOSSDK v2.4.11 [Debug] AWSURLResponseSerialization.m line:63 | -[AWSJSONResponseSerializer responseObjectForResponse:originalRequest:currentRequest:data:error:] | Response body: {"IdentityId":"eu-west-1:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"} 2016-12-27 12:43:35.766 AskHub[26625:10037234] Identity id: eu-west-1:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX



但是,当我运行以下代码来访问 protected 终端节点时,CloudFront 认为我未通过身份验证。
APIHealthClient *apiClient = [APIHealthClient defaultClient];
APIAskHubRequest *initReq = [[APIAskHubRequest alloc] init];
initReq.message = @"FIN";

NSLog(@"Sending initial request");
[[apiClient webhooksAskhubPost:initReq] continueWithBlock:^id(AWSTask *task) {
if (task.error) {
NSLog(@"Could not send initial request: %@", task.error);
} else if (task.exception) {
NSLog(@"Could not send initial request: %@", task.exception);
} else {
NSLog(@"Successfully sent initial request");
}

return nil;
}];

回应:

2016-12-27 12:56:25.247 AskHub[26784:10046562] Could not send initial request: Error Domain=com.amazonaws.AWSAPIGatewayErrorDomain Code=1 "(null)" UserInfo={HTTPBody={ message = Unauthorized; }, HTTPHeaderFields={type = immutable dict, count = 9, entries => 3 : Via = {contents = "X.X XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.cloudfront.net (CloudFront)"} 4 : x-amzn-ErrorType = {contents = "UnauthorizedException"} 5 : Content-Type = {contents = "application/json"} 6 : Content-Length = {contents = "27"} 7 : Connection = {contents = "keep-alive"} 8 : x-amzn-RequestId = {contents = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"} 9 : Date = {contents = "Tue, 27 Dec 2016 11:56:25 GMT"} 10 : X-Cache = {contents = "Error from cloudfront"} 11 : X-Amz-Cf-Id = {contents = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"} } }



我在这里错过了什么吗?自动生成的 SDK 是否支持 User Pool 认证?

最佳答案

根据我看到的代码,您正在清除凭据但从未获得凭据。快速回顾一下,您似乎正确设置了服务配置和身份验证,但您从未调用凭据。

如果是这种情况,即使您的应用程序将进行身份验证,凭据提供程序也永远不会获取登录字典。

(您可以在 AWS 控制台中验证这一点,如果您查看您尝试用于访问资源的 identityId,您可以查看“登录”计数。如果为 0,则表示您没有登录。)

为了进行身份验证,您需要让凭据提供程序调用您的 identityProviderManager “登录”方法。

当您执行 SDK 中的“凭据”“getCredentialsForIdentity”时,就会发生该调用。

通常,该序列是 GetID 后跟 GetCredentialsForId。在 IOS SDK 中,GetId 与“getSession”一起发生(所以你应该拥有它),GetCredentials 与“credentials”一起发生

(请注意,每个 SDK 中都有不同的命名(例如 Mobile Hub 与 IOS SDK),但重要的是您的凭据提供程序获取登录字典。使用详细日志记录,您实际上应该看到记录的“登录”字典,其中将向您证明正在向凭据提供程序提供登录字典)。

关于ios - API Gateway 为授权用户生成带有 Cognito 用户池的 iOS SDK (Objective-C),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41344908/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com