更新时间: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 =https://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.