使用 Facebook 和 Google+ 提供商身份验证的 Amazon Cognito iOS SDK V2 的问题
Issues with Amazon Cognito iOS SDK V2 using Facebook and Google+ Provider Authentication
我目前无法授权用户使用 AWS iOS SDK V2,使用 Facebook 和 Google+ 作为提供商。
我不确定这是我在 AWS 开发人员控制台上的设置,还是代码。
这是身份池的角色策略:
{
"Version": "2012-10-17",
"Statement": [{
"Action": [
"mobileanalytics:PutEvents",
"cognito-sync:*"
],
"Effect": "Allow",
"Resource": ["*"]
}]
我确实收到了未经授权的 Cognito ID,但是当我尝试使用 Facebook 或 Google+ 提供商身份验证时,它不起作用。
Facebook 登录后returns 我可以成功使用用户属性提取个人资料图片、姓名和电子邮件地址。然后我从 Facebook 会话中获取令牌(是的,它是一个很长的字符串)并在 deviceID class:
中使用它
- (void)loginViewFetchedUserInfo:(FBLoginView *)loginView
user:(id<FBGraphUser>)user {
//Populate viewcontoller with Facebook data
self.profilePictureView.profileID = user.id;
NSRange range = [user.name rangeOfString:@" "];
self.firstName.text = [user.name substringToIndex:range.location];
self.lastName.text = [user.name substringFromIndex:range.location+1];
self.emailAddress.text = [user objectForKey:@"email"];
//Get Facebook token, set then get Cognito device ID - in DeviceId class
NSString *token = FBSession.activeSession.accessTokenData.accessToken;
DeviceId *myDeviceId = [DeviceId sharedInstance];
cognitoDeviceId = [myDeviceId setFacebookToken:token];
}
DeviceID class实现如下所示:
#import "DeviceId.h"
#import <AWSiOSSDKv2/AWSCore.h>
#import <AWSCognitoSync/Cognito.h>
@implementation DeviceId
static NSString *cognitoId;
static DeviceId *_sharedInstance;
static AWSCognitoCredentialsProvider *credentialsProvider;
static AWSServiceConfiguration *configuration;
+ (DeviceId *) sharedInstance
{
if (!_sharedInstance)
{
_sharedInstance = [[DeviceId alloc] init];
}
return _sharedInstance;
}
- (NSString *) getDeviceId
{
return cognitoId;
}
- (void) setDeviceId
{
/*
* AWS Cognito
*/
credentialsProvider = [AWSCognitoCredentialsProvider
credentialsWithRegionType:AWSRegionUSEast1
accountId:@"(accountID"
identityPoolId:@"(identityPool)"
unauthRoleArn:@"arn:aws:iam::(accountID):role/Cognito_(app)UsersUnauth_DefaultRole"
authRoleArn:@"arn:aws:iam::(accountID):role/Cognito_(app)UsersAuth_DefaultRole"];
configuration = [AWSServiceConfiguration configurationWithRegion:AWSRegionUSEast1
credentialsProvider:credentialsProvider];
[AWSServiceManager defaultServiceManager].defaultServiceConfiguration = configuration;
// Retrieve the cognito ID.
cognitoId = credentialsProvider.identityId;
if (!cognitoId) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Identification Error"
message:@"Error on User Account."
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}
}
-(NSString *)setFacebookToken:(NSString*)token {
credentialsProvider.logins = @{ @(AWSCognitoLoginProviderKeyFacebook): token };
[self setDeviceId];
return cognitoId;
}
-(NSString *)setGooglePlusToken:(NSString*)token {
credentialsProvider.logins = @{ @(AWSCognitoLoginProviderKeyGoogle): token };
[self setDeviceId];
return cognitoId;
}
@end
我没有收到任何错误消息,上面的仪表板从不显示经过身份验证的用户。 CognitoID 从不更改其值。谁能告诉我问题出在哪里?
编辑:根据评论更新DeviceId.m cognitoId returns nil
编辑 2:更新 DeviceId.m 以替换 while 循环检查 BFTask 是否已完成到 Bolts 方法 waitUntilFinished。
#import "DeviceId.h"
#import <AWSiOSSDKv2/AWSCore.h>
#import <AWSCognitoSync/Cognito.h>
@implementation DeviceId
{
__block NSString *tempCognitoId;
}
static NSString *cognitoId;
static DeviceId *_sharedInstance;
static AWSCognitoCredentialsProvider *credentialsProvider;
static AWSServiceConfiguration *configuration;
+ (DeviceId *) sharedInstance
{
if (!_sharedInstance)
{
_sharedInstance = [[DeviceId alloc] init];
}
return _sharedInstance;
}
- (NSString *) getDeviceId
{
return cognitoId;
}
- (void) setDeviceId
{
/*
* AWS Cognito
*/
credentialsProvider = [AWSCognitoCredentialsProvider
credentialsWithRegionType:AWSRegionUSEast1
identityPoolId:@"Identity Pool ID"];
configuration = [AWSServiceConfiguration
configurationWithRegion:AWSRegionUSEast1
credentialsProvider:credentialsProvider];
[AWSServiceManager defaultServiceManager].defaultServiceConfiguration = configuration;
BFTask *taskIdentity = [[credentialsProvider refresh] continueWithBlock:^id(BFTask *task){
if (task.error == nil)
{
tempCognitoId = credentialsProvider.identityId;
NSLog(@"cognitoId: %@", cognitoId);
}
else
{
NSLog(@"Error : %@", task.error);
}
return nil;
}];
[taskIdentity waitUntilFinished];
cognitoId = tempCognitoId;
}
-(NSString *)setFacebookToken:(NSString*)token {
credentialsProvider.logins = @{ @(AWSCognitoLoginProviderKeyFacebook): token };
BFTask *taskIdentity = [[credentialsProvider refresh] continueWithBlock:^id(BFTask *task){
if (task.error == nil)
{
tempCognitoId = credentialsProvider.identityId;
NSLog(@"cognitoId: %@", tempCognitoId);
}
else
{
NSLog(@"Error : %@", task.error);
}
return nil;
}];
[taskIdentity waitUntilFinished];
cognitoId = tempCognitoId;
return cognitoId;
}
-(NSString *)setGooglePlusToken:(NSString*)token {
credentialsProvider.logins = @{ @(AWSCognitoLoginProviderKeyGoogle): token };
BFTask *taskIdentity = [[credentialsProvider getIdentityId] continueWithBlock:^id(BFTask *task){
if (task.error == nil)
{
tempCognitoId = credentialsProvider.identityId;
NSLog(@"cognitoId: %@", tempCognitoId);
}
else
{
NSLog(@"Error : %@", task.error);
}
return nil;
}];
[taskIdentity waitUntilFinished];
cognitoId = tempCognitoId;
return cognitoId;
}
@end
我确实意识到有些人可能认为等待完成是不好的做法,但我需要确保出于测试目的返回 cognitoId "synchronously"。修改Facebook App ID后,使用此方法返回cognitoID。
编辑 3:但是,Google+ 在到达 deviceId 之前失败。
- (void)finishedWithAuth:(GTMOAuth2Authentication *)auth
error:(NSError *)error {
if (error) {
_signInAuthStatus.text =
[NSString stringWithFormat:@"Status: Authentication error: %@", error];
NSLog(@"%@", error);
return;
}
NSString *idToken = [auth.parameters objectForKey:@"id_token"];
DeviceId *myDeviceId = [DeviceId sharedInstance];
[myDeviceId setGooglePlusToken:idToken];
}
NSLog 错误打印:Error Domain=com.google.GooglePlusPlatform Code=-1 "The operation couldn’t be completed. (com.google.HTTPStatus error 400.)" The API & Auth Product Name and Current Email Address appeared to correct on the console.
编辑 4:代码的另一部分中的 Cognito Synch 现在已停止工作,而它之前可以工作:
AWSCognito *syncClient = [AWSCognito defaultCognito];
AWSCognitoDataset *dataset = [syncClient openOrCreateDataset:@"myDataSet"];
NSString *fullName = [dataset stringForKey:@"name"];
在第一行失败并出现错误:
*** 由于未捕获的异常 'NSInvalidArgumentException' 而终止应用程序,原因:'+[AWSEndpoint endpointWithRegion:service:]:无法识别的选择器已发送至 class
感谢任何有关这些额外错误的帮助。
看起来,在 credentialsProvider.logins 映射中设置令牌后,您正在通过再次调用 setDeviceId 来覆盖您的 credentialsProvider。 setDeviceId 创建一个全新的 AWSCognitoCredentialsProvider,它将没有您添加到前一个的令牌,并覆盖变量 credentialsProvider。
您在
中描述的问题的常见原因
Error Domain=com.google.GooglePlusPlatform Code=-1 "操作无法完成。(com.google.HTTPStatus 错误 400。)
在this Whosebug question中有描述。我会仔细检查您是否输入了产品名称和电子邮件地址。此外,我认为您必须在输入此数据后重新创建 OAuth 凭据,因此如果您还没有这样做,可能值得一试。
最后,检查您使用的是网络服务器 API 密钥,而不是 iOS 客户端密钥。
我目前无法授权用户使用 AWS iOS SDK V2,使用 Facebook 和 Google+ 作为提供商。
我不确定这是我在 AWS 开发人员控制台上的设置,还是代码。
这是身份池的角色策略:
{
"Version": "2012-10-17",
"Statement": [{
"Action": [
"mobileanalytics:PutEvents",
"cognito-sync:*"
],
"Effect": "Allow",
"Resource": ["*"]
}]
我确实收到了未经授权的 Cognito ID,但是当我尝试使用 Facebook 或 Google+ 提供商身份验证时,它不起作用。
Facebook 登录后returns 我可以成功使用用户属性提取个人资料图片、姓名和电子邮件地址。然后我从 Facebook 会话中获取令牌(是的,它是一个很长的字符串)并在 deviceID class:
中使用它- (void)loginViewFetchedUserInfo:(FBLoginView *)loginView
user:(id<FBGraphUser>)user {
//Populate viewcontoller with Facebook data
self.profilePictureView.profileID = user.id;
NSRange range = [user.name rangeOfString:@" "];
self.firstName.text = [user.name substringToIndex:range.location];
self.lastName.text = [user.name substringFromIndex:range.location+1];
self.emailAddress.text = [user objectForKey:@"email"];
//Get Facebook token, set then get Cognito device ID - in DeviceId class
NSString *token = FBSession.activeSession.accessTokenData.accessToken;
DeviceId *myDeviceId = [DeviceId sharedInstance];
cognitoDeviceId = [myDeviceId setFacebookToken:token];
}
DeviceID class实现如下所示:
#import "DeviceId.h"
#import <AWSiOSSDKv2/AWSCore.h>
#import <AWSCognitoSync/Cognito.h>
@implementation DeviceId
static NSString *cognitoId;
static DeviceId *_sharedInstance;
static AWSCognitoCredentialsProvider *credentialsProvider;
static AWSServiceConfiguration *configuration;
+ (DeviceId *) sharedInstance
{
if (!_sharedInstance)
{
_sharedInstance = [[DeviceId alloc] init];
}
return _sharedInstance;
}
- (NSString *) getDeviceId
{
return cognitoId;
}
- (void) setDeviceId
{
/*
* AWS Cognito
*/
credentialsProvider = [AWSCognitoCredentialsProvider
credentialsWithRegionType:AWSRegionUSEast1
accountId:@"(accountID"
identityPoolId:@"(identityPool)"
unauthRoleArn:@"arn:aws:iam::(accountID):role/Cognito_(app)UsersUnauth_DefaultRole"
authRoleArn:@"arn:aws:iam::(accountID):role/Cognito_(app)UsersAuth_DefaultRole"];
configuration = [AWSServiceConfiguration configurationWithRegion:AWSRegionUSEast1
credentialsProvider:credentialsProvider];
[AWSServiceManager defaultServiceManager].defaultServiceConfiguration = configuration;
// Retrieve the cognito ID.
cognitoId = credentialsProvider.identityId;
if (!cognitoId) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Identification Error"
message:@"Error on User Account."
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}
}
-(NSString *)setFacebookToken:(NSString*)token {
credentialsProvider.logins = @{ @(AWSCognitoLoginProviderKeyFacebook): token };
[self setDeviceId];
return cognitoId;
}
-(NSString *)setGooglePlusToken:(NSString*)token {
credentialsProvider.logins = @{ @(AWSCognitoLoginProviderKeyGoogle): token };
[self setDeviceId];
return cognitoId;
}
@end
我没有收到任何错误消息,上面的仪表板从不显示经过身份验证的用户。 CognitoID 从不更改其值。谁能告诉我问题出在哪里?
编辑:根据评论更新DeviceId.m cognitoId returns nil
编辑 2:更新 DeviceId.m 以替换 while 循环检查 BFTask 是否已完成到 Bolts 方法 waitUntilFinished。
#import "DeviceId.h"
#import <AWSiOSSDKv2/AWSCore.h>
#import <AWSCognitoSync/Cognito.h>
@implementation DeviceId
{
__block NSString *tempCognitoId;
}
static NSString *cognitoId;
static DeviceId *_sharedInstance;
static AWSCognitoCredentialsProvider *credentialsProvider;
static AWSServiceConfiguration *configuration;
+ (DeviceId *) sharedInstance
{
if (!_sharedInstance)
{
_sharedInstance = [[DeviceId alloc] init];
}
return _sharedInstance;
}
- (NSString *) getDeviceId
{
return cognitoId;
}
- (void) setDeviceId
{
/*
* AWS Cognito
*/
credentialsProvider = [AWSCognitoCredentialsProvider
credentialsWithRegionType:AWSRegionUSEast1
identityPoolId:@"Identity Pool ID"];
configuration = [AWSServiceConfiguration
configurationWithRegion:AWSRegionUSEast1
credentialsProvider:credentialsProvider];
[AWSServiceManager defaultServiceManager].defaultServiceConfiguration = configuration;
BFTask *taskIdentity = [[credentialsProvider refresh] continueWithBlock:^id(BFTask *task){
if (task.error == nil)
{
tempCognitoId = credentialsProvider.identityId;
NSLog(@"cognitoId: %@", cognitoId);
}
else
{
NSLog(@"Error : %@", task.error);
}
return nil;
}];
[taskIdentity waitUntilFinished];
cognitoId = tempCognitoId;
}
-(NSString *)setFacebookToken:(NSString*)token {
credentialsProvider.logins = @{ @(AWSCognitoLoginProviderKeyFacebook): token };
BFTask *taskIdentity = [[credentialsProvider refresh] continueWithBlock:^id(BFTask *task){
if (task.error == nil)
{
tempCognitoId = credentialsProvider.identityId;
NSLog(@"cognitoId: %@", tempCognitoId);
}
else
{
NSLog(@"Error : %@", task.error);
}
return nil;
}];
[taskIdentity waitUntilFinished];
cognitoId = tempCognitoId;
return cognitoId;
}
-(NSString *)setGooglePlusToken:(NSString*)token {
credentialsProvider.logins = @{ @(AWSCognitoLoginProviderKeyGoogle): token };
BFTask *taskIdentity = [[credentialsProvider getIdentityId] continueWithBlock:^id(BFTask *task){
if (task.error == nil)
{
tempCognitoId = credentialsProvider.identityId;
NSLog(@"cognitoId: %@", tempCognitoId);
}
else
{
NSLog(@"Error : %@", task.error);
}
return nil;
}];
[taskIdentity waitUntilFinished];
cognitoId = tempCognitoId;
return cognitoId;
}
@end
我确实意识到有些人可能认为等待完成是不好的做法,但我需要确保出于测试目的返回 cognitoId "synchronously"。修改Facebook App ID后,使用此方法返回cognitoID。
编辑 3:但是,Google+ 在到达 deviceId 之前失败。
- (void)finishedWithAuth:(GTMOAuth2Authentication *)auth
error:(NSError *)error {
if (error) {
_signInAuthStatus.text =
[NSString stringWithFormat:@"Status: Authentication error: %@", error];
NSLog(@"%@", error);
return;
}
NSString *idToken = [auth.parameters objectForKey:@"id_token"];
DeviceId *myDeviceId = [DeviceId sharedInstance];
[myDeviceId setGooglePlusToken:idToken];
}
NSLog 错误打印:Error Domain=com.google.GooglePlusPlatform Code=-1 "The operation couldn’t be completed. (com.google.HTTPStatus error 400.)" The API & Auth Product Name and Current Email Address appeared to correct on the console.
编辑 4:代码的另一部分中的 Cognito Synch 现在已停止工作,而它之前可以工作:
AWSCognito *syncClient = [AWSCognito defaultCognito];
AWSCognitoDataset *dataset = [syncClient openOrCreateDataset:@"myDataSet"];
NSString *fullName = [dataset stringForKey:@"name"];
在第一行失败并出现错误:
*** 由于未捕获的异常 'NSInvalidArgumentException' 而终止应用程序,原因:'+[AWSEndpoint endpointWithRegion:service:]:无法识别的选择器已发送至 class
感谢任何有关这些额外错误的帮助。
看起来,在 credentialsProvider.logins 映射中设置令牌后,您正在通过再次调用 setDeviceId 来覆盖您的 credentialsProvider。 setDeviceId 创建一个全新的 AWSCognitoCredentialsProvider,它将没有您添加到前一个的令牌,并覆盖变量 credentialsProvider。
您在
中描述的问题的常见原因Error Domain=com.google.GooglePlusPlatform Code=-1 "操作无法完成。(com.google.HTTPStatus 错误 400。)
在this Whosebug question中有描述。我会仔细检查您是否输入了产品名称和电子邮件地址。此外,我认为您必须在输入此数据后重新创建 OAuth 凭据,因此如果您还没有这样做,可能值得一试。
最后,检查您使用的是网络服务器 API 密钥,而不是 iOS 客户端密钥。