我想将 facebook 访问 token 发送到 AWS Cognito,然后接收一个授权 token ,该 token 可以进一步作为 HTTP Put 请求中的授权 header 发送。 但是,我总是从 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 响应
实际结果:未经授权
最佳答案
您从 API 网关收到 unauthorized
响应的原因是双重的:
credentialsProvider.credentials()
未序列化为 JSON,并且不能“按原样”用于授权 header 。看起来您正在尝试通过自行管理 URL 请求的低级别详细信息来手动调用 API 网关。我没有看到向请求添加签名的代码。所有经过身份验证的 API 网关请求都必须签名(请参阅 https://docs.aws.amazon.com/apigateway/api-reference/making-http-requests/ )并且授权 header 必须包含用于计算签名的凭据。
管理 AWS 签名的底层细节并非易事。您不应该编写代码来执行此操作,而应使用 AWS iOS SDK反而。特别是,如果您尝试使用 Cognito 用户池授权调用 API 网关,请查看此示例:https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-generate-sdk-ios-swift.html .
API 网关控制台将生成运行此示例所需的客户端代码(请参阅 https://docs.aws.amazon.com/apigateway/latest/developerguide/genearte-ios-sdk-of-an-api.html)
这应该会从您的代码中删除大量样板代码,使其更易于阅读和维护。
在您上面的评论中发布的流程,iOS SDK 将自动为您处理 2/3/和 4/步骤。
关于ios - swift: 在将 facebook 当前 token 发送到 AWS Cognito 后接收 AWS id_token?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54504124/