Using soto-cognito-authentication-kit

204 Views Asked by At

I need to implement native authentication with AWS Cognito and I am trying to use https://github.com/adam-fowler/soto-cognito-authentication-kit in my iOS App (client side).

I am struggling with the usage of the CognitoAuthenticatable object for starting a username/password auth.

Here is my code:

class LoginHandler {
    func handleLogin(username: String, password: String) {
        var eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1)

        let data = AWSCognitoContext()
        let response = self.authenticatable.authenticate(
            username: username,
            password: password,
            requireAuthenticatedClient: false,
            clientMetadata: nil,
            context: data,
            on: eventLoopGroup.next()
        )

        response.flatMap { response in
            // use response object
        }
    }
}

class AWSCognitoContext: CognitoContextData {
    var contextData: CognitoIdentityProvider.ContextDataType? {
        return CognitoIdentityProvider.ContextDataType(
            httpHeaders: [],
            ipAddress: "",
            serverName: "",
            serverPath: "")
    }
}

The authenticate method is supposed to return EventLoopFuture<CognitoAuthenticateResponse>

  1. How to handle the response of the authenticate method? I am getting the error Generic parameter 'NewValue' could not be inferred
  2. How to construct the CognitoContextData object. I just want to use the default values for AWS server location.
1

There are 1 best solutions below

0
On

The authenticate function returns immediately with the EventLoopFuture<...>. It is fulfilled at a later point with the result of the authenticate when it has completed. The EventLoopFuture object has a number of ways to process this results. The simplest is whenComplete. You could do the following

response.whenComplete { result in
    switch result {
    case .failure(let error):
        process error ...
    case .success(let response):
        process authenticate response
    }
}

You would use map if you want to process the response object. eg

response.map { response -> NextObject in
    return CreateNextObject(from: response)
}

You would use flatMap if you want to chain multiple EventLoopFutures together. eg

response.flatMap { response -> EventLoopFuture<NextObject> in
    return CreateEventLoopFutureNextObject(from: response)
}

If you are having issues with could not be inferred errors it is always good to be explicit about what your closures are returning.

The swift nio docs will give you more info https://apple.github.io/swift-nio/docs/current/NIO/Classes/EventLoopFuture.html

The context data is to provide context to Cognito of where this authenticate request is coming from. This isn't really used when requireAuthenticatedClient is false. So providing an empty context is ok.

One other thing you shouldn't be creating an EventLoopGroup in your function. It is creating threads which can be time consuming and you then have to shutdown them down when all the processes are complete. You can use the eventLoopGroup here authenticatable.configuration.cognitoIDP.eventLoopGroup