且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

AWS的iOS SDK Cognito开发人员认证(SWIFT)

更新时间:2023-12-03 10:21:04

我相信我已经想通了。我需要利用BFTask这是专为处理后台任务与完成。

有关的人与Cognito一个迅速执行开​​发商的认证谁可能有类似的设置对我挣扎,我这是怎么实现的:

 类ExampleAppIdentityProvider:AWSAbstractCognitoIdentityProvider {
    VAR _token:字符串!
    VAR _logins:[NSObject的:AnyObject]!

    //头的东西,你可能并不需要,但我的身份验证使用我的服务器
    让acceptHeader =应用/ vnd.exampleapp-API + JSON;版本= 1;
    让authHeader =令牌记号=
    让userDefaults = NSUserDefaults.standardUserDefaults()
    我们的authToken = self.userDefaults.valueForKey(authentication_token)作为字符串

    //终点,我的服务器给亚马逊identityId和令牌授权用户
    让URL =htt​​ps://api.myapp.com/api/amazon_id/

    覆盖VAR令牌:字符串{
        得到 {
            返回_token
        }
    }

    覆盖VAR登录:[NSObject的:AnyObject]! {
        得到 {
            返回_logins
        }
        组 {
            _logins =为newValue
        }
    }

    覆盖FUNC getIdentityId() -  GT; BFTask! {
        如果self.identityId!=零{
            返回BFTask(结果:self.identityId)
        }其他{
            返回BFTask(结果:无)!.continueWithBlock({(任务) - > AnyObject在
                如果self.identityId ==零{
                    返回self.refresh()
                }
                返回BFTask(结果:self.identityId)
            })
        }
    }

    覆盖FUNC刷新() -  GT; BFTask! {
        让工作= BFTaskCompletionSource()
        让我们请求= AFHTT prequestOperationManager()
        request.requestSerializer.setValue(self.acceptHeader,forHTTPHeaderField:接受)
        request.requestSerializer.setValue(self.authHeader +的authToken,forHTTPHeaderField:授权)
        request.GET中(self.url,参数:无,成功:{(要求:AFHTT prequestOperation!回应:AnyObject) - >太虚了!
            //需要以下3条线为参考这里:http://***.com/a/26741208/535363
            VAR TMP = NSMutableDictionary的()
            tmp.setObject(温度,forKey:为ExampleApp)
            self.logins = TMP

            //从我的服务器响应获取的属性
            让属性:NSDictionary的= response.objectForKey(物业)作为NSDictionary的
            让amazonId = properties.objectForKey(amazon_identity)作为字符串
            让amazonToken = properties.objectForKey(令牌)为String

            //设置identityId和令牌的ExampleAppIdentityProvider
            self.identityId = amazonId
            self._token = amazonToken

            task.setResult(响应)
        },失败:{(要求:AFHTT prequestOperation!错误:NSError) - >虚空中
            task.setError(错误)
        })
        返回task.task
    }
}
 

和初始化 ExampleAppIdentityProvider 这样做:

 让identityProvider = ExampleAppIdentityProvider()
    让credentialsProvider = AWSCognitoCredentialsProvider(regionType:AWSRegionType.USEast1,identityProvider:identityProvider,unauthRoleArn:GlobalVariables.cognitoUnauthRoleArn,authRoleArn:GlobalVariables.cognitoAuthRoleArn)
    让defaultServiceConfiguration = AWSServiceConfiguration(地区:.USEast1,credentialsProvider:credentialsProvider)
    AWSServiceManager.defaultServiceManager()。defaultServiceConfiguration = defaultServiceConfiguration

    让transferManager = AWSS3TransferManager.defaultS3TransferManager()

    让uploadRequest = AWSS3TransferManagerUploadRequest()
    uploadRequest.bucket = GlobalVariables.awsBucket
    uploadRequest.key =\(GlobalVariables.environment)/上传/用户/ \(用户ID)/ \(类型)/ \(时间戳)/original.jpg
    uploadRequest.ACL = .AuthenticatedRead
    uploadRequest.body = tmpFileUrl

    // 上传文件
    让工作= transferManager.upload(uploadRequest)
 

我创建了一个结构 GlobalVariables 与保存值的全局环境变量 unAuthRoleArn authRoleArn 等。当然,你不必这样做,但我提到它,以防有人迷茫。

I am having a hard time figuring out how to return developer credentials provided by my server (via AWS) to my Example identity provider.

It seems I need to do this synchronously within the refresh method on the ExampleIdentityProvider class. I'm using AFNetworking to make the request, but it is an async GET request. How can I do this synchronously for the refresh method on my IdentityProvider?

The following is in Swift:

class ExampleIdentityProvider: AWSAbstractIdentityProvider  {
    var newToken: String!

    override var token: String {
        get {
            return newToken
        }
        set {
            newToken = newValue
        }
    }

    override func getIdentityId() -> BFTask! {
        if self.identityId != nil {
            return BFTask(result: self.identityId)
        }else{
            return BFTask(result: nil).continueWithBlock({ (task) -> AnyObject! in
                if self.identityId == nil {
                    return self.refresh()
                }
                return BFTask(result: self.identityId)
            })
        }
    }

    override func refresh() -> BFTask! {
        return BFTask(result: nil).continueWithBlock({ (task) -> AnyObject! in
            let result =  AFNETWORKING REQUEST FOR CREDENTIALS TO MY SERVER
            self.identityId = result.identityId
            self.token = result.token

            return BFTask(result: self.identityId)
        })
    }
}

I believe I have figured it out. I needed to utilize BFTask which is built for handling background tasks with completion.

For people struggling with a Swift implementation of developer authentication with Cognito who might have a similar setup to me, this is how I accomplished it:

class ExampleAppIdentityProvider: AWSAbstractCognitoIdentityProvider {
    var _token: String!
    var _logins: [ NSObject : AnyObject ]!

    // Header stuff you may not need but I use for auth with my server
    let acceptHeader = "application/vnd.exampleapp-api+json;version=1;"
    let authHeader = "Token token="
    let userDefaults = NSUserDefaults.standardUserDefaults()
    let authToken = self.userDefaults.valueForKey("authentication_token") as String

    // End point that my server gives amazon identityId and tokens to authorized users
    let url = "https://api.myapp.com/api/amazon_id/"

    override var token: String {
        get {
            return _token
        }
    }

    override var logins: [ NSObject : AnyObject ]! {
        get {
            return _logins
        }
        set {
            _logins = newValue
        }
    }

    override func getIdentityId() -> BFTask! {
        if self.identityId != nil {
            return BFTask(result: self.identityId)
        }else{
            return BFTask(result: nil).continueWithBlock({ (task) -> AnyObject! in
                if self.identityId == nil {
                    return self.refresh()
                }
                return BFTask(result: self.identityId)
            })
        }
    }

    override func refresh() -> BFTask! {
        let task = BFTaskCompletionSource()
        let request = AFHTTPRequestOperationManager()
        request.requestSerializer.setValue(self.acceptHeader, forHTTPHeaderField: "ACCEPT")
        request.requestSerializer.setValue(self.authHeader+authToken, forHTTPHeaderField: "AUTHORIZATION")
        request.GET(self.url, parameters: nil, success: { (request: AFHTTPRequestOperation!, response: AnyObject!) -> Void in
            // The following 3 lines are required as referenced here: http://***.com/a/26741208/535363
            var tmp = NSMutableDictionary()
            tmp.setObject("temp", forKey: "ExampleApp")
            self.logins = tmp

            // Get the properties from my server response
            let properties: NSDictionary = response.objectForKey("properties") as NSDictionary
            let amazonId = properties.objectForKey("amazon_identity") as String
            let amazonToken = properties.objectForKey("token") as String

            // Set the identityId and token for the ExampleAppIdentityProvider
            self.identityId = amazonId
            self._token = amazonToken

            task.setResult(response)
        }, failure: { (request: AFHTTPRequestOperation!, error: NSError!) -> Void in
            task.setError(error)
        })
        return task.task
    }
}

And initialized the ExampleAppIdentityProvider by doing:

    let identityProvider = ExampleAppIdentityProvider()
    let credentialsProvider = AWSCognitoCredentialsProvider(regionType: AWSRegionType.USEast1, identityProvider: identityProvider, unauthRoleArn: GlobalVariables.cognitoUnauthRoleArn, authRoleArn: GlobalVariables.cognitoAuthRoleArn)
    let defaultServiceConfiguration = AWSServiceConfiguration(region: .USEast1, credentialsProvider: credentialsProvider)
    AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = defaultServiceConfiguration

    let transferManager = AWSS3TransferManager.defaultS3TransferManager()

    let uploadRequest = AWSS3TransferManagerUploadRequest()
    uploadRequest.bucket = GlobalVariables.awsBucket
    uploadRequest.key = "\(GlobalVariables.environment)/uploads/users/\(userId)/\(type)/\(timestamp)/original.jpg"
    uploadRequest.ACL = .AuthenticatedRead
    uploadRequest.body = tmpFileUrl

    // Upload file
    let task = transferManager.upload(uploadRequest)

I created a struct named GlobalVariables with global environment variables that hold values for bucket, unAuthRoleArn, authRoleArn, etc. Of course you don't have to do that, but I'm mentioning it in case someone is confused.