swift: получать AWS id_token после отправки текущего токена Facebook в AWS Cognito? - PullRequest
0 голосов
/ 03 февраля 2019

Я хочу отправить токен доступа на 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 _ {
    }
}

}

Ожидаемый результат: ответ JSON с сервера AWSФактический результат: не авторизован

1 Ответ

0 голосов
/ 03 февраля 2019

Причина, по которой вы получаете unauthorized ответ от API Gateway, является двойной:

  1. credentialsProvider.credentials() не сериализовано в JSON и не может быть "как есть" дляЗаголовки авторизации.

  2. Похоже, вы пытаетесь вручную вызвать API-шлюз, управляя самостоятельно низкоуровневыми деталями запроса URL.Я не вижу кода для добавления подписи к запросу.Все аутентифицированные запросы API-шлюза должны быть подписаны (см. https://docs.aws.amazon.com/apigateway/api-reference/making-http-requests/), а заголовок авторизации должен содержать учетные данные, используемые для вычисления подписи.

Управление низкоуровневыми деталями AWS Signatureне является тривиальным. Вы не должны писать код для этого, но вместо этого используйте AWS iOS SDK . В частности, если вы пытаетесь вызвать API-шлюз с авторизацией Cognito User Pool, посмотрите на этот пример: 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 / шагах для вас - автоматически.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...