在这里回答: 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
})
}
}
然而我收到错误:
错误Domain = com.amazonaws.AWSCognitoIdentityErrorDomain Code = 8&#34;(null)&#34; UserInfo = {__ type = NotAuthorizedException,message =登录不匹配。请至少包含一个此身份或身份池的有效登录信息。}
如果您对如何解决我的问题有任何疑问,请与我们联系。我还尝试过关注文档并直接设置登录信息&#34; credentialsProvider.logins = {&#34; graph.facebook.com&#34;:mytoken}
并且在调用lambda方法时产生一个不同的异常,但是DOES正确地检索了identityID。但是,根据文档进行操作会发出警告,即我使用的方法已被弃用。
我得到的错误:
UserInfo = {NSLocalizedDescription =序列化对象既不是有效的json对象也不是NSData对象:}
然而,这有时只会发生。如果我重试然后我可能会获得身份ID但是在调用lambda方法时,我得到相同的错误。我认为这是一个认知问题。
更新
如果我在第一部分使用AWSCognitoLoginProviderKey.facebook.rawValue而不是graph.facebook.com,那么它会给我一个cognito ID,然后我调用lambda方法。我将包含lambda方法,只是因为我遇到了错误的部分,但我确信它的认知正在阻止我调用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 |无法刷新。错误是[错误域= com.amazonaws.AWSCognitoIdentityErrorDomain Code = 10&#34;(null)&#34; UserInfo = {__ type = ResourceNotFoundException,message = Identity&#39; us-east-1:0db18266-1baa-4c59-9110-f9041dc92ead&#39;找不到。}]
我认为看起来像identitypoolID的大字符串实际上是我拥有的给定用户的identityID,因此cognito已经分发了一个ID但是无法查询它?
答案 0 :(得分:0)
错误:
登录不匹配。请至少包含一个此身份或身份池的有效登录信息
也可能因为您尝试以另一个用户身份登录而未注销,因此将登录字典中的令牌与identityId进行比较以获得不同的身份(并且不匹配)。在这种情况下,SDK通常通过重试,清除和重新建立identityId来恢复,然后它可以工作。
但是在您的情况下,因为您正在构建自己的登录词典,所以问题更可能是您构造了一个不匹配的令牌。您可以使用https://jwt.io检查令牌。 (虽然我承认它适用于谷歌和认知用户池,但不适用于facebook令牌(我不知道为什么会这样)),
我认为不匹配意味着identityId记录了与令牌中指定的不同的唯一用户。
您确定令牌是否构造正确吗?
正如你提到的......文档......好吧..我发现文档不值得一看,所以我设置了项目,以便查看工作代码并设置断点。
以下是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-mobilehub-helper-ios中的一些修复才能使用他们在这里的Cognito用户池aws-mobilehub-helper-ios(所以如果克隆做一个克隆--recursive,你将被设置为调试在库中使用断点)。
答案 1 :(得分:0)
我认为很少有事情可以发挥作用。
我通过创建自己的identityprovidermanager做出了正确的举动,我认为阻止我执行lambda方法的主要原因实际上是我使用的是AWSLambda而不是AWSLambdaInvoker。切换后,它开始制作有意义的错误。