【问题标题】:How to get Unauthenticated identity using Swift如何使用 Swift 获取未经身份验证的身份
【发布时间】:2016-02-06 10:42:48
【问题描述】:

我已经按照this AWS Developer Guide 初始化了凭据提供程序。我不确定它是否有效,以及如何检查。我似乎找不到任何关于如何在 Swift 中使用 Cognito 的文档。我将它作为单元测试运行,测试通过,print("identityId", identityId) 行输出:

identityId <AWSTask: 0x17d5fde0; completed = NO; cancelled = NO; faulted = NO;>

但是,在调试期间,identityProvider.identityId 属性为 nil。

这是我的文件:

// MyAuth.swift

import Foundation
import AWSCognito

class MyAuth {

    func getUnauthCognitoId()->Bool {
        let identityProvider = MyIdentityProvider()
        let credentialsProvider = AWSCognitoCredentialsProvider(regionType: AWSRegionType.USEast1, identityProvider: identityProvider, unauthRoleArn: Constants.ARNUnauth.value, authRoleArn: Constants.ARNAuth.value)
        let defaultServiceConfiguration = AWSServiceConfiguration(region: .USEast1, credentialsProvider: credentialsProvider)
        AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = defaultServiceConfiguration

        if let identityId = identityProvider.getIdentityId() {
            print("identityId", identityId)
            return true
        } else {
            return false
        }

    }

}

还有

//  MyIdentityProvider.swift

import Foundation
import AWSCognito

class MyIdentityProvider: 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/"

    func authenticatedWithProvider()->Bool {
        if let logins = _logins {
            return logins["ProviderName"] == nil
        }
        else {
            return false
        }
    }

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

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

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

    override func refresh() -> AWSTask! {
        let task = AWSTaskCompletionSource()
        if(!self.authenticatedWithProvider()) {
            return super.getIdentityId()
        }
        else {
            // TODO: Authenticate with developer
            return task.task
        }
        /*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://stackoverflow.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
    }
}

import XCTest
@testable import My

class MyTests: XCTestCase {

    override func setUp() {
        super.setUp()
        // Put setup code here. This method is called before the invocation of each test method in the class.
    }

    override func tearDown() {
        // Put teardown code here. This method is called after the invocation of each test method in the class.
        super.tearDown()
    }

    func testExample() {
        // This is an example of a functional test case.
        // Use XCTAssert and related functions to verify your tests produce the correct results.
    }

    func testPerformanceExample() {
        // This is an example of a performance test case.
        self.measureBlock {
            // Put the code you want to measure the time of here.
        }
    }

    func testGetUnauthCognitoId() {
        let myAuth = MyAuth()
        XCTAssertTrue(myAuth.getUnauthCognitoId())
    }

}

【问题讨论】:

  • 对我来说,identityid 似乎是零。在page 上有一些有趣的示例可以让凭据提供程序在 iOS 中工作。他们也有一些有趣的预建测试用例。我看了一眼,提供的页面似乎与您的问题相关。顺便说一句 - 如果您只想从 repo 下载单个文件夹,请查看此 SO Q&A
  • 编辑:我已经编辑了我更改的代码,特别是我实现了一个 AWSAbstractCognitoIdentityProvider 并且不确定它是否成功检索身份。
  • 顺便说一句 - 你在设备上运行这个吗?
  • @Tommie C. 是的,作为单元测试

标签: swift amazon-web-services amazon-cognito


【解决方案1】:

事实证明,如果你在应用程序中创建一个默认的服务配置:didFinishLaunchingWithOptions: 你的应用程序委托文件中的应用程序委托方法as described here:

let credentialsProvider = AWSCognitoCredentialsProvider(
        regionType: AWSRegionType.USEast1, identityPoolId: cognitoIdentityPoolId)

let defaultServiceConfiguration = AWSServiceConfiguration(
        region: AWSRegionType.USEast1, credentialsProvider: credentialsProvider)

AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = defaultServiceConfiguration

每当您尝试使用任何 AWS 服务时,开发工具包都会使用未经身份验证的身份,并且您不一定需要创建 cognitoIdentity 对象。

【讨论】:

【解决方案2】:

getIdentityId 返回一个AWSTask。由于AWSTask 本质上是BFTask,但名称不同,因此您可以使用continueWithBlock syntax shown on the BFTask page 获取identityId。比如:

credentialProvider.getIdentityId().continueWithBlock {
    (task: AWSTask!) -> AWSTask in
    if task.error() {
        // failed to retrieve identityId.
    } else {
        print("identityId", task.result())
    }

【讨论】:

  • 这是有道理的,但它是否可以进行单元测试(因为它是异步代码),如果可以,如何?
  • 我想我知道如何使用这篇文章了:blog.dadabeatnik.com/2014/07/13/…
  • 是的,通常单元测试框架会有办法处理异步代码。在 iOS 中尤其如此,因为所有网络调用都应该是异步的。我用过 kiwi,他们在github.com/kiwi-bdd/Kiwi/wiki/Asynchronous-Testing 有一些关于此的文档@
  • 我在原始问题中没有看到错误。您在调试器中看到的输出是对 AWSTask 实例的引用。因此,如果您按照上述方式更新了代码,您肯定不会看到。您能否提供您正在使用的更新代码并给出您看到的逐字错误消息。
  • 我会更新一个,我的代码最近到处都是,但我发现身份是nil
猜你喜欢
  • 2019-09-25
  • 2015-10-12
  • 1970-01-01
  • 2021-07-05
  • 1970-01-01
  • 2019-06-14
  • 2019-09-13
  • 1970-01-01
  • 2015-05-19
相关资源
最近更新 更多