【问题标题】:swift:receive AWS id_token after sending facebook current token to AWS Cognito?swift:将facebook当前令牌发送到AWS Cognito后接收AWS id_token?
【发布时间】:2019-06-27 11:37:20
【问题描述】:

我想将 facebook 访问令牌发送到 AWS Cognito,然后接收一个授权令牌,该令牌可以进一步作为 HTTP Put 请求中的授权标头发送。 但是,我总是从 AWS 端点收到“未经授权”的响应。

当我尝试打印时:

    credentialsProvider.credentials().continueOnSuccessWith(executor: AWSExecutor.default()) { (task) -> Any? in
            print(task.error)
            return true
        }

我得到以下输出:

Optional(Error Domain=com.amazonaws.AWSJSONBuilderErrorDomain Code=4 "serialized object is neither a valid json Object nor NSData object: {
    IdentityPoolId = "******";
    Logins =     {
        "graph.facebook.com" = "<FBSDKAccessToken: *******>";
    };
}" UserInfo={NSLocalizedDescription=serialized object is neither a valid json Object nor NSData object: {
    IdentityPoolId = "*****+*";
    Logins =     {
        "graph.facebook.com" = "<FBSDKAccessToken: ******>";
    };
}})

这是我的代码:

import AWSCognito
class FacebookProvider: NSObject, AWSIdentityProviderManager {
    func logins() -> AWSTask<NSDictionary> {
        if let token = FBSDKAccessToken.current() {
            return AWSTask(result: [AWSIdentityProviderFacebook:token])
        }
        return AWSTask(error:NSError(domain: "Facebook Login", code: -1 , userInfo: ["Facebook" : "No current Facebook access token"]))
    }
}

class API {
..............

public func putOrder(when fbLogin: Bool, _ order: Order, onSuccess: @escaping(JSON) -> Void,
                         on Failure: @escaping(Error)-> Void) {
        let credentialsProvider = AWSCognitoCredentialsProvider(regionType: .EUCentral1 ,
                                                                identityPoolId:"*****", identityProviderManager:FacebookProvider())
    let configuration = AWSServiceConfiguration(region: AWSRegionType.EUCentral1, credentialsProvider: credentialsProvider)
    AWSServiceManager.default().defaultServiceConfiguration = configuration
    let url = "\(serverURL)\(API.loginOrderPath)"
    let urlRequest: NSMutableURLRequest = NSMutableURLRequest(url: NSURL(string: url)! as URL)
    urlRequest.httpMethod = API.apiMethodPut
    urlRequest.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
    urlRequest.setValue("\(credentialsProvider.credentials())", forHTTPHeaderField: "Authorization")
    do {
        var json: JSON
        json = ["companyId": order.companyId, "drinks": order.drinksId, "payment": order.payment, "tip": order.tip]
        urlRequest.httpBody = try json.rawData()
        let task = URLSession.shared.dataTask(with: urlRequest as URLRequest, completionHandler: {data, response, error -> Void in
            if error != nil {
                Failure(error!)
            } else {
                if let response = try? JSON(data: data!) {
                    onSuccess(response)
                } else {
                }
            }
        })
        task.resume()
    } catch _ {
    }
}

}

预期结果:来自 AWS 服务器的 JSON 响应
实际结果:未经授权

【问题讨论】:

  • 能否将创建 Cognito 凭据提供程序的代码添加到问题中?
  • 我还没有创建任何。这是我唯一的代码。
  • 好吧,credentialsProvider 变量已经在某处创建并初始化了,不是吗?
  • 你能分享一下代码吗?如果不查看您的代码,很难提供帮助。
  • 我刚刚重新格式化了我的问题,现在问题中的代码更加清晰。 .它在 API 类中初始化——在 putOrder(..) 方法中。

标签: ios swift facebook amazon-web-services amazon-cognito


【解决方案1】:

您收到来自 API Gateway 的 unauthorized 响应的原因是双重的:

  1. credentialsProvider.credentials() 未序列化为 JSON,不能“原样”用于授权标头。

  2. 看起来您正在尝试手动调用 API 网关,方法是管理您自己的 URL 请求的低级别详细信息。我没有看到向请求添加签名的代码。所有经过身份验证的 API 网关请求都必须经过签名(请参阅 https://docs.aws.amazon.com/apigateway/api-reference/making-http-requests/),并且 Authorization 标头必须包含用于计算签名的凭据。

管理 AWS 签名的低级细节并非易事。您不应该为此编写代码,而是使用 AWS iOS SDK。特别是,如果您尝试使用 Cognito 用户池授权调用 API 网关,请查看以下示例:https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-generate-sdk-ios-swift.html

API Gateway 控制台将生成运行此示例所需的客户端代码(请参阅https://docs.aws.amazon.com/apigateway/latest/developerguide/genearte-ios-sdk-of-an-api.html

这应该会从您的代码中删除很多样板,使其更易于阅读和维护。

您在上面的评论中发布的流程,iOS SDK 将自动为您处理 2/ 3/ 和 4/ 步骤。

【讨论】:

  • 感谢您的回复。这适用于身份池或用户池吗?
  • 两者。身份池允许使用标准 IAM 访问控制 (docs.aws.amazon.com/apigateway/latest/developerguide/…),Cognito 用户池记录在此处docs.aws.amazon.com/apigateway/latest/developerguide/…
  • 谢谢。那非常有帮助。如何将通过 Facebook 登录收到的 Facebook 身份验证令牌作为授权标头发送到 Amazon Cognito 身份池
  • 另外,这仅适用于托管 UI 还是也适用于显式添加的 facebook 登录按钮?
  • Cognito ID 池没有托管 GUI。托管 GUI 仅适用于 Cognito 用户池。
猜你喜欢
  • 2017-02-25
  • 2019-04-23
  • 2017-02-09
  • 1970-01-01
  • 2015-09-19
  • 1970-01-01
  • 2021-10-25
  • 2019-05-28
  • 2018-03-07
相关资源
最近更新 更多