问题
I use the latest version of aws-ios-sdk with Objective-C which is 2.4.16 I think. I used Lambdaauth from the internet as a baseline. I did all the Lambda functions in node 4.3 and then access them from my iOS device using the the api gateway.
So for instance after a user has registers I call a class in my iOS (auth class) that uses NSURLSessions and NSURLRequests to pass the JSON back and forth to the gateway which calls the appropriate Lambda function.
So to login it passes in the email and password to the gateway and to the Lambda function. The lambda function then authenticates with the users table and everything else then runs this function:
function getToken(userId, fn)
{
var param =
{
IdentityPoolId: "us-east-1:identityPoolId”,
Logins: {} // To have provider name in a variable
};
// uses a unique user id
param.Logins["com.website.login”] = userId;
cognitoidentity.getOpenIdTokenForDeveloperIdentity(param,
function(err, data)
{
if (err) return fn(err); // an error occurred
else fn(null, data.IdentityId, data.Token); // successful response
});
}
The userId and data.IdentityId and data.Token all get passed back through the gateway and into the iOS device and stored in user default settings/preferences (the code below reads @"stored in device".
Then I have the following classes in iOS to handle the authenticated users based off documentation:
// DeveloperAuthenticated.h
import <AWSCore/AWSCore.h>
@interface DeveloperAuthenticated : AWSCognitoCredentialsProviderHelper
@end
// DeveloperAuthenticated.m
#import "DeveloperAuthenticated.h"
@implementation DeveloperAuthenticated
/*
* Use the token method to communicate with your backend to get an
* identityId and token.
*/
- (AWSTask <NSString *> *) token
{
NSString *identityId = @"stored in device";
NSString *token = @"stored in device";
// Set the identity id and return the token
self.identityId = identityId;
return [AWSTask taskWithResult:token];
}
/* - (AWSTask <NSString *> *) getIdentityId
{
SString *identityId = @"stored in device";
NSString *token = @"stored in device";
// Set the identity id and return the token
self.identityId = identityId;
return [AWSTask taskWithResult: identityId];
} */
- (AWSTask<NSDictionary<NSString *, NSString *> *> *)logins
{
NSString *userId = @"stored in device";
// NSString *token = @"stored in device";
if(userId == nil)
{
return [AWSTask taskWithResult:nil];
}
else
{
// NSDictionary *user = [NSDictionary dictionaryWithObjectsAndKeys:@"ccognito-identity.amazonaws.com", token, nil];
// return [AWSTask taskWithResult: user];
return [super logins];
}
}
The above code is probably somewhat wrong as it never seems to hit the break points that I set. But anyway after everything is logged in (after lambda runs above) I have this to try and access a dynamoDB table but it’s still in Unauth mode:
DeveloperAuthenticated *authenticate = [[DeveloperAuthenticated alloc] initWithRegionType:AWSRegionUSEast1 identityPoolId:@"us-east-1:identityPoolId” useEnhancedFlow:YES identityProviderManager:nil];
AWSCognitoCredentialsProvider *credentialsProvider = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionUSEast1 identityProvider:authenticate];
// AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1 credentialsProvider:credentialsProvider];
// [AWSServiceManager defaultServiceManager].defaultServiceConfiguration = configuration;
[credentialsProvider clearCredentials];
// credentialsProvider.logins = @"";
AWSDynamoDB *dynamoDB = [AWSDynamoDB defaultDynamoDB];
// NSDictionary<NSString *, NSString *> *login = [self logins];
// Just a table in dynamoDB that has a class wrapper to test an insert
Blogposts *posts = [Blogposts new];
posts.postId = @"test";
AWSDynamoDBObjectMapper *dynamoDBObjectMapper = [AWSDynamoDBObjectMapper defaultDynamoDBObjectMapper];
[[dynamoDBObjectMapper save:posts] continueWithBlock:^id(AWSTask *task)
{
if (task.error)
{
// Always end up here since unearth is the role and not auth with dynamodb access
NSLog(@"The request failed. Error: [%@]", task.error);
}
if (task.exception)
{
NSLog(@"The request failed. Exception: [%@]", task.exception);
}
if (task.result)
{
// Do something with the result.
}
return nil;
}];
Questions:
Cognito is all setup correctly but the role never switches from unauth to auth.
I am not sure how to make it switch to auth roles. I don’t know how to use the AWSServiceManager and have no idea on a refresh function at all. I also wish the user would remain in auth role once it happens for say 2 weeks or longer like most apps do.
Error from Xcode IDE
{"__type":"com.amazon.coral.service#AccessDeniedException","Message":"User: arn:aws:sts::123456789:assumed-role/CognitoTheAppIdentityPoolUnauth/CognitoIdentityCredentials is not authorized to perform: dynamodb:UpdateItem on resource: arn:aws:dynamodb:us-east-1:123456789:table/Photos"} 2017-02-23 01:42:05.534 The request failed. Error: [Error Domain=com.amazonaws.AWSServiceErrorDomain Code=6 "(null)" UserInfo={__type=com.amazon.coral.service#AccessDeniedException, Message=User: arn:aws:sts::123456789:assumed-role/CognitoTheAppIdentityPoolUnauth/CognitoIdentityCredentials is not authorized to perform: dynamodb:UpdateItem on resource: arn:aws:dynamodb:us-east-1:123456789:table/Photos}]
来源:https://stackoverflow.com/questions/42108904/using-aws-developer-identities-for-authentication-for-ios-objective-c