【问题标题】:AWS Cognito integration swift3 Refresh provides ResourceNotFoundExceptionAWS Cognito 集成 swift3 Refresh 提供 ResourceNotFoundException
【发布时间】:2017-03-10 07:38:45
【问题描述】:

按照这里的答案: https://github.com/aws/aws-sdk-ios/issues/357 在最底部有一个关于如何快速和认知工作的迷你指南。

我已经创建了一个 AWSCustomIdentityProvider:

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
        })
    }
}

但是我得到了错误:

错误域=com.amazonaws.AWSCognitoIdentityErrorDomain Code=8 "(null)" UserInfo={__type=NotAuthorizedException, message=Logins 不匹配。请为此身份或身份池提供至少一个有效登录信息。}

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

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

我得到的错误:

UserInfo={NSLocalizedDescription=序列化对象既不是有效的 json 对象也不是 NSData 对象:}

但是,这种情况有时会发生。如果我重试,那么我可能会获得身份 ID,但在调用 lambda 方法时,我会得到同样的错误。我假设这是一个认知问题。

更新

如果我在第一部分使用 AWSCognitoLoginProviderKey.facebook.rawValue 而不是 graph.facebook.com,那么它会给我 cognito ID,然后我调用 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 | __44-[AWSCognitoCredentialsProvider 凭证]_block_invoke.352 |无法刷新。错误是 [Error Domain=com.amazonaws.AWSCognitoIdentityErrorDomain Code=10 "(null)" UserInfo={__type=ResourceNotFoundException, message=Identity 'us-east-1:0db18266-1baa-4c59-9110-f9041dc92ead' not found.} ]

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

【问题讨论】:

    标签: swift3 facebook-ios-sdk aws-lambda amazon-cognito aws-sdk-ios


    【解决方案1】:

    错误:

    登录名不匹配。请为此身份或身份池提供至少一个有效的登录信息

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

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

    我认为不匹配意味着 identityId 记录的唯一用户与令牌中指定的不同。

    您确定令牌构造正确吗?

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

    这是来自 Mobile Hub Helper 的 Facebook AWSSignInProvider 的代码的 sn-p,其中显示了他们用于获取令牌 (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 的 Identity 部分做得非常好

    我在 github 上发布了该库的一个版本,它也为 Cognito 用户池添加了 AWSSignInProvider。 SignIn-awsmhh 它需要在 aws-mobilehub-helper-ios 中进行一些修复才能使用他们在这里的 cognito 用户池 aws-mobilehub-helper-ios (因此,如果您克隆执行克隆 --recursive 并且您将设置为使用中的断点进行调试图书馆)。

    【讨论】:

    • 我使用过 Objective C,虽然我更喜欢它,但我需要快速编码。 Facebook的swift SDK使用“authenticationToken”而不是tokenString,这个authenticationToken可能是我的问题。您认为是这种情况还是我应该以另一种方式处理?
    【解决方案2】:

    我认为很少有事情使它起作用。

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

    【讨论】:

    • 您好,您是否有任何文档可供参考以制作您自己的身份提供者管理器?如果你有那么请与我们分享,然后它会创造一些场景。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-26
    • 2021-09-23
    • 1970-01-01
    • 2018-11-01
    • 1970-01-01
    • 2019-12-02
    • 2019-07-21
    相关资源
    最近更新 更多