2015-02-14 20 views
5

Tôi đang gặp khó khăn trong việc tìm cách trả lại thông tin đăng nhập của nhà phát triển do máy chủ của tôi cung cấp (qua AWS) cho nhà cung cấp danh tính Ví dụ của tôi.AWS iOS SDK Xác thực Nhà phát triển Cognito (Swift)

Có vẻ như tôi cần thực hiện đồng bộ hóa này trong phương thức refresh trên lớp ExampleIdentityProvider. Tôi đang sử dụng AFNetworking để thực hiện yêu cầu, nhưng đó là yêu cầu không đồng bộ GET. Làm thế nào tôi có thể làm điều này đồng bộ cho phương pháp làm mới trên IdentityProvider của tôi?

Sau đây là trong 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) 
     }) 
    } 
} 

Trả lời

11

Tôi tin rằng tôi đã tìm nó ra. Tôi cần sử dụng BFTask được xây dựng để xử lý các tác vụ nền khi hoàn thành.

Đối với những người đang gặp khó khăn với việc thực hiện Swift xác thực nhà phát triển với Cognito người có thể có một thiết lập tương tự với tôi, đây là cách tôi thực hiện nó:

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://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 
    } 
} 

Và khởi tạo các ExampleAppIdentityProvider bằng cách thực hiện:

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) 

Tôi đã tạo một struct có tên GlobalVariables với các biến môi trường toàn cầu giữ giá trị cho bucket, unAuthRoleArn, authRoleArn, v.v ... O Tất nhiên bạn không cần phải làm điều đó, nhưng tôi đề cập đến nó trong trường hợp ai đó đang bối rối.

+0

bạn có thể thấy cách bạn khởi tạo các nhà cung cấp/cấu hình cho những thứ AWS để sử dụng này ? – user871177

+0

@ user871177 xem mã được cập nhật ở trên. Hy vọng đó là hữu ích. – Yavin4

+0

wow, rất hữu ích. –

0

bạn có thể tạo cho bạn lớp tùy chỉnh cho cognito xác thực

import AWSS3 
import AWSCore 
import Alamofire 

//This variable is store aws credential token 
var cachedLogin : NSDictionary? 
final class AmazonIdentityProvider : AWSCognitoCredentialsProviderHelper{ 

    // Handles getting the login 
    override func logins() -> AWSTask<NSDictionary> { 
     guard let cachedLoginObj = cachedLogin else { 
      return getCredentials().continueWith(block: { (credentialTask) -> AWSTask<NSDictionary> in 
       guard let credential = credentialTask.result else { 
        return AWSTask(result: nil) 
       } 

       self.setCognitoTokenKey(credential: credential) 

       return AWSTask(result: cachedLogin) 
      }) as! AWSTask<NSDictionary> 
     } 
     return AWSTask(result: cachedLoginObj) 
    } 

    // Handles getting a token from the server 
    override func token() -> AWSTask<NSString> { 
     return getCredentials().continueWith(block: { (credentialTask) -> AWSTask<NSString> in 
      guard let credential = credentialTask.result else { 
       return AWSTask(result: nil) 
      } 

      self.setCognitoTokenKey(credential: credential) 

      return AWSTask(result: credential.token as NSString) 
     }) as! AWSTask<NSString> 
    } 

    // Handles getting the identity id 
    override func getIdentityId() -> AWSTask<NSString> { 

     return getCredentials().continueWith(block: { (credentialTask) -> AWSTask<NSString> in 
      guard let credential = credentialTask.result else { 
       return AWSTask(result: nil) 
      } 

      self.setCognitoTokenKey(credential: credential) 

      return AWSTask(result: credential.identityId as NSString) 
     }) as! AWSTask<NSString> 
    } 

    //This method is used to AWS Token set 
    func setCognitoTokenKey(credential : AmazonCognitoCredential){ 
     let login: NSDictionary = ["cognito-identity.amazonaws.com": credential.token] 
     cachedLogin = login 
     self.identityId = credential.identityId 
    } 

    // Gets credentials from server 
    func getCredentials() -> AWSTask<AmazonCognitoCredential> { 
     let tokenRequest = AWSTaskCompletionSource<AmazonCognitoCredential>() 
     getAwsToken { (isSuccess, error, credentials) in 
      if isSuccess 
      { 
       tokenRequest.set(result: credentials) 
      } 
      else 
      { 
       tokenRequest.set(error: error!) 
      } 
     } 
     return tokenRequest.task 
    } 
    typealias CompletionBlock = (_ success:Bool,_ errorMassage:Error?,_ responce:AmazonCognitoCredential?) -> Void 
    func getAwsToken(complitionBlock : @escaping CompletionBlock) { 
//Your server token code 
} 
/// AmazonCognito credential custom class 
final class AmazonCognitoCredential { 
    let token: String 
    let identityId: String 

    init(token: String, identityId: String) { 
     self.token = token 
     self.identityId = identityId 
    } 
} 

và bạn có thể sử dụng trong ứng dụng của đại biểu

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 

    AWSDDLog.sharedInstance.logLevel = .all 
    let identityProvider = AmazonIdentityProvider() 
    let credentialsProvider = AWSCognitoCredentialsProvider(regionType: .USEast1, unauthRoleArn: CognitoRoleUnauth, authRoleArn: CognitoRoleAuth, identityProvider: identityProvider) 
    let configuration = AWSServiceConfiguration(region: .USWest2, credentialsProvider: credentialsProvider) 
    AWSServiceManager.default().defaultServiceConfiguration = configuration 

    let task = identityProvider.getIdentityId() 
    task.continueWith { (task:AWSTask) -> Any? in 
     if (task.error != nil) { 
      print("\(String(describing: task.error))") 
     } else { 
      print("Task result: \(String(describing: task.result))") 
     } 
     return nil 
    } 
    return true 
} 
Các vấn đề liên quan