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

AWS Cognito集成swift3刷新提供ResourceNotFoundException

殷永嘉
2023-03-14

答案如下:https://github.com/aws/aws-sdk-ios/issues/357 在最底层有一个关于如何让swift和cognito发挥作用的迷你指南。

我已经做了一个AWSCustom鉴定提供者这样:

import Foundation
import AWSCognitoIdentityProvider
import AWSCognito

class AWSCustomIdentityProvider: NSObject, AWSIdentityProviderManager
{

private var dict = NSDictionary()

func addToken(value:NSString)
{
    dict = ["graph.facebook.com":value]
}

public func logins() -> AWSTask<NSDictionary>
{
    return AWSTask(result: dict)
}
}

我有一个来自facebook的登录方法:

public func loginButtonDidCompleteLogin(_ loginButton: FacebookLogin.LoginButton, result: FacebookLogin.LoginResult){

    switch result {
    case .failed(let error):
        print("FACEBOOK LOGIN FAILED: \(error)")
    case .cancelled:
        print("User cancelled login.")
    case .success(_, _, let accessToken):


        let customIdentity = AWSCustomIdentityProvider()
        let token = accessToken.authenticationToken
        customIdentity.addToken(value: token as NSString)

        let credentialsProvider = AWSCognitoCredentialsProvider(regionType: REGIONTYPE, identityPoolId: "XXXXXXXXXXXXXXXXXXXXXXX", identityProviderManager:customIdentity)

        credentialsProvider.clearKeychain()
        credentialsProvider.clearCredentials()

        let serviceConfiguration = AWSServiceConfiguration(region: REDIONTYPE, credentialsProvider: credentialsProvider)
        AWSServiceManager.default().defaultServiceConfiguration = serviceConfiguration;

        credentialsProvider.getIdentityId().continue( { (task: AWSTask!) -> AnyObject! in
            if (task.error != nil) {
                print("Error: " + (task.error?.localizedDescription)!)// gets called
            }
            else {
                print(task.result)//identityid
            }
            return nil
        })
    }
}

但是我得到了一个错误:

Error Domain=com.amazonaws.AWSCognitoIdentityErrorDomain Code=8“(null)”UserInfo={{uuuu type=NotAuthorizedException,message=Logins不匹配。请为此标识或标识池至少包含一个有效的登录名。}

如果你对如何解决我的问题有任何想法,请告诉我。我也尝试过跟踪文档并直接设置登录名“credentialsProvider.logins={”graph.facebook.com“:mytoken}

这会在调用lambda方法时产生一个不同的异常,但确实正确地检索了identityID。但是,根据文档进行操作会发出警告,我使用的方法已被弃用。

我得到的错误是:

序列化对象既不是有效的json对象,也不是NSData对象:}

然而,这只是偶尔发生。如果我重试,然后我可能会得到身份标识,但在调用lambda方法,我得到同样的错误。我想这是一个认知问题。

更新

如果我在第一部分中使用AWSCognitoLoginProviderKey.facebook.rawValue而不是graph.facebook.com,那么它会给我cognitoid,然后我调用lambda方法。我将包括lambda方法,以防万一这是我出错的部分,但我可以肯定是cognito阻止我调用lambda方法:

import AWSLambda
import Foundation
struct AWSHelper{
let lambda = AWSLambda.default()
let APPLICATION_NAME = "MYAPPLICATION"
init(){

}

func getFunctionName(funcName: String) -> String{
    return "\(funcName)_\(APPLICATION_NAME)"
}

func login(facebookID: String, cognitoID:String, callback:@escaping (Bool) -> Void){
    let req = AWSLambdaInvocationRequest();
    req?.invocationType = AWSLambdaInvocationType.requestResponse
    req?.payload = ["cognitoID" : cognitoID, "facebookID" : facebookID]
    req?.functionName = getFunctionName(funcName: "MYFUNCNAME")

    lambda.invoke(req!) { (response: AWSLambdaInvocationResponse?,error: Error?) in
        print(error)
        let payload = response?.payload
        print(payload)
        callback(true)
    }

}
}

更新2

我发现调用这样的刷新方法:

credentialsProvider.credentials().continue({ (task: AWSTask!) -> Any? in
            print(task.result)
        })

导致如下错误:

AWSiOSSDK v2.4.10[错误]AWSCredentialsProvider.m行:577 | | uu44-[AWSCognitoCredentialsProvider凭据]\u block |无法刷新。错误为[Error Domain=com.amazonaws.AWSCognitoIdentityErrorDomain Code=10”(null)“UserInfo={{uuuu type=ResourceNotFoundException,message=Identity'us-east-1:0db18266-1baa-4c59-9110-f9041dc92ead'未找到。}]

我相信看起来像identitypoolID的大字符串实际上是我拥有的给定用户的identityID,所以cognito分发了一个ID,但无法查询它?

共有2个答案

严易安
2023-03-14

我想没有什么能让它成功的。

我通过制作自己的identityprovidermanager做出了正确的举动,我认为阻止我执行lambda方法的主要原因实际上是我使用了AWSLambda而不是AWSLambdaInvoker。在我切换之后,它开始犯一些有意义的错误。

张通
2023-03-14

错误:

登录名不匹配。请为此标识或标识池至少包含一个有效登录名

也可能发生这种情况,因为您试图在不注销的情况下以另一用户身份登录,因此会将登录字典中的令牌与不同标识的标识ID进行比较(并且不匹配)。在这种情况下,SDK通常通过重试、清除和重新建立identityId来恢复,然后就可以工作了。

但在您的情况下,因为您正在构建自己的登录字典,所以问题更可能是您构建了一个不匹配的令牌。您可以使用https://jwt.io. (虽然我承认它适用于谷歌和cognito用户池,但不适用于facebook代币(我不知道这是为什么)),

我认为不匹配意味着标识ID记录了一个不同于令牌中指定的唯一用户。

您确定令牌构造正确吗?

正如你提到的...留档...我发现留档不值得看,所以我设置了我的项目,这样我就可以查看工作代码并设置断点。

以下是Mobile Hub Helper的Facebook AWSSignInProvider中的代码片段,其中显示了他们使用什么来获取令牌(token.tokenstring)。

    - (AWSTask<NSString *> *)token {
    FBSDKAccessToken *token = [FBSDKAccessToken currentAccessToken];
    NSString *tokenString = token.tokenString;
    NSDate *idTokenExpirationDate = token.expirationDate;

    if (tokenString
        // If the cached token expires within 10 min, tries refreshing a token.
        && [idTokenExpirationDate compare:[NSDate dateWithTimeIntervalSinceNow:AWSFacebookSignInProviderTokenRefreshBuffer]] == NSOrderedDescending) {
        return [AWSTask taskWithResult:tokenString];
    }

    AWSTaskCompletionSource *taskCompletionSource = [AWSTaskCompletionSource taskCompletionSource];
    [FBSDKLoginManager renewSystemCredentials:^(ACAccountCredentialRenewResult result, NSError *error) {
        if (result == ACAccountCredentialRenewResultRenewed) {
            FBSDKAccessToken *token = [FBSDKAccessToken currentAccessToken];
            NSString *tokenString = token.tokenString;
            taskCompletionSource.result = tokenString;
        } else {
            taskCompletionSource.error = error;
        }
    }];
    return taskCompletionSource.task;
}

而且值得一提。AWSIdentityManager及其关联的AWSSignInProviders是一个很好的架构,可以登录Facebook和Google。即使您不使用Mobile Hub Helper的其余部分。为什么要重新发明轮子,他们在aws mobilehub helper ios的标识部分做得非常好

我在github上发布了该库的一个版本,该版本还为Cognito用户池添加了AWSSignInProvider。SignIn-awsmhh需要在aws-mobile ehub-helper-ios中进行一些修复才能使用认知用户池,它们就在这里aws-mobile ehub-helper-ios(因此,如果克隆执行克隆-递归,则将设置为使用库中的断点进行调试)。

 类似资料:
  • 仅需几行代码就可以为UITableView加上下拉刷新或者上拉刷新功能。可以自定义上下拉刷新的文字说明。具体使用看下面的“使用方法”。 作者说:网上开源的下拉-上拉刷新控件,普遍封装得过于复杂、耦合性强。因此本人特地花了点时间写了一套无耦合、可插拔式的刷新控件,对项目中的其他代码毫无侵入性,而且使用简单,3行代码就能集成刷新控件。 [Code4App.com]

  • 如何通过提供已配置用户的用户名和密码获得AWS令牌表单? 我想做的是有一个URL,它接受user/pass作为postparams并返回一个令牌。这里记录的三个“允许的OAuth流”都没有这个或任何其他网址 编辑:邮递员怎么做?我正在寻找类似于: 调用aws url并为池中的某个用户提供user/Pass AWS返回一个令牌 包括令牌与资源服务器的每个请求 资源服务器验证令牌

  • 问题内容: 在JPA中,如果我们调用EntityTransaction.commit(),它会自动调用EntityManager.flush()吗?还是我们都应该称呼它们?有什么区别?因为我在使用JPA时遇到问题,所以当我向数据库中插入实体时,我会调用persist()。在数据库中,数据已插入(可以获取),但是该数据未显示在我的应用程序中(我使用findAll()进行获取)。在另一个实体上,它出现

  • 在JPA中,如果我们调用EntityTransaction。commit(),它是否自动调用EntityManager。flush()?或者我们应该叫他们两个?有什么区别?因为我对JPA有问题,当我向数据库插入实体时,我调用persist()。在数据库中,数据已经插入(可以提取),但该数据没有显示在我的应用程序中(我使用findAll()提取)。在另一个实体上,它出现了。有什么我不知道的吗?我使用

  • 我从“dynconfigflows”-目录中加载xml配置文件,然后动态创建IntegrationFlow。 每个xml文件一个IntegrationFlow。如果配置文件已编辑,则应更新IntegrationFlow。IntegrationFlow的注册id被设置为配置文件名。 ,因此当前的流应该平稳地停止(没有更多的输入消息和当前处理的消息应该完成)。在此之后,应该删除它,并注册流的更新版本。

  • 我们有一个WebSphere JMS Queue和QueueConnectionFactory,提供程序为IBM MQ。我们不能直接连接到IBM MQ。 我有以下配置-我有bean jmsConnectionFactory,它使用InitialContext创建工厂。_queue是我的队列的JNDI名称 它因错误而失败 由:com.ibm.msg.client.jms.DetailedInvali