2015-04-27 25 views
6

Sto implementando lo Uber's Request Endpoint nella mia app iOS (Swift). La richiesta API/Endpoint richiede l'autenticazione dell'utente con l'app, ecco lo doc.Uber Le credenziali OAuth 2.0 non valide hanno fornito l'autenticazione Uber in ios Swift

Per questo sto usando questo Oauth2.0 library

Quello che ho fatto è

  1. integrato con successo la Biblioteca nel mio progetto (xCode) con l'aiuto di determinati istruzioni per l'installazione.

  2. Nel mio AppDelegate

    let uber_OAuth_Settings = [ 
    "client_id": "XXXXXXX9vtKzobvXXXXXX", 
    "client_secret": "EXXXXXXXXyFUNCa_Wez6AXXXXXXXnrXtxus", 
    "authorize_uri": "https://login.uber.com/oauth/authorize", 
    "token_uri": "https://login.uber.com/oauth/token", 
    "redirect_uris": ["jamesappv2://oauth/callback"], // don't forget to register this scheme 
    ] as OAuth2JSON 
    

    var OAuth: OAuth2CodeGrant!

  3. nel mio metodo didFinishLaunchingWithOptions di AppDelegate

    oauth = OAuth2CodeGrant(settings: uber_OAuth_Settings) 
    oauth.viewTitle = "Uber Login Service"  // optional 
    oauth.verbose = true // For Logs 
    
  4. Non dimenticare di registrare URL regime cioè ("redirect_uris": ["jamesappv2://oauth/callback"])

goto di destinazione della tua app -> informazioni TAB -> tipi di URL -> Fare clic su (+), immagine allegata

enter image description here

  1. In AppDelegate aggiungere il metodo indicato di seguito e Maneggiare l'Callback URL

    func application(application: UIApplication, 
    openURL url: NSURL, 
    sourceApplication: String?, 
    annotation: AnyObject?) -> Bool { 
        // you should probably first check if this is your URL being opened 
    
        var splitUrl = url.absoluteString!.componentsSeparatedByString(":") 
    
        if splitUrl[0] == ("jamesappv2") { 
    
         oauth.handleRedirectURL(url) 
        } 
    
        return true 
    } 
    
  2. Ora nel mio viewController ho fatto come questo su myBtnClick

    let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate 
    
    let url = appDelegate.oauth.authorizeURL() 
    UIApplication.sharedApplication().openURL(url)   
    appDelegate.oauth.onAuthorize = { parameters in 
        println("Did authorize with parameters: \(parameters)") 
    
        self.navigationController?.pushViewController(self.PersonalDriverUber_VC, animated: true) 
    //On Authorization Goto another ViewController using pushViewController of navigationcontroller Method 
    
    } 
    appDelegate.oauth.onFailure = { error in  // `error` is nil on cancel 
        if nil != error { 
         println("Authorization went wrong: \(error!.localizedDescription)") 
        } 
    } 
    

Ecco il mio registro di debug, sto ricevendo la risposta valida:

OAuth2: Handling redirect URL jamesappv2://oauth/callback?state=4B0EB812&code=0sXXXXXXTX7yEbS1XXXXXHuw 
OAuth2: Successfully validated redirect URL 
OAuth2: Authorizing against https://login.uber.com/oauth/token?state=38158941&grant_type=authorization_code&code=0sXXXXXXXX1jxTrdFQT9Huw&client_secret=EIXXXXXXXNCa_Wez6XXXXXw0BlnrXtxus&client_id=fXXXXXXXy2LOUo9vtKXXXXXQ1nUDO&redirect_uri=jamesappv2%3A%2F%2Foauth%2Fcallback 
OAuth2: Exchanging code 0swNXXXXX7yXXXXXXdFQT9Huw with redirect jamesappv2://oauth/callback for token at Optional("https://login.uber.com/oauth/token") 
OAuth2: Did receive access token: Dfq3XXXXXXuWgpaqFXXXXXXXgXW, refresh token: EmStT7FEXHRMlS8odPzs1nsha0ObjK 
Did authorize with parameters: [token_type: Bearer, expires_in: 2592000, access_token: XXXXXXOZuWgXXXXXXXXuJYOmgXW, refresh_token: EXXXXXHRMlS8oXXXXXXXa0ObjK, scope: profile, last_authenticated: 1430121470] 

Avviso Sto ricevendo il valido access_token

Qui mi sono bloccato

Come da DOCs dice in STEP4 * USE PORTATORE GETTONE

Passare l'access_token restituito nella risposta in l'intestazione Authorization con il tipo Bearer per effettuare richieste per conto di un utente. *

curl -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' 'https://api.uber.com/v1/products?latitude=37.7759792&longitude=-122.41823' 

Non ho capito il punto. Come dovrei passare access_token nell'intestazione con il tipo Bearer?Ho fatto come qui di seguito

func callRequestAPI(url:String){ 

    let request = appDelegate.oauth.request(forURL: NSURL(string:url)!) 



    request.HTTPMethod = "POST" 


    let postString = "product_id="+selectedUberProductId+"&start_latitude="+start_lat+"&start_longitude="+start_lng+"&end_latitude="+end_lat+"&end_longitude="+end_lng 

    println(postString) 


    let tempData: NSData = appDelegate.oauth.accessToken.dataUsingEncoding(NSUTF8StringEncoding)! 
    let base64LoginString = tempData.base64EncodedStringWithOptions(nil) 

    request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding) 
    request.addValue("application/json", forHTTPHeaderField: "Content-Type") 
    request.addValue("application/json", forHTTPHeaderField: "Accept") 




    request.setValue("Bearer \(base64LoginString)", forHTTPHeaderField: "Authorization") 

    let session = NSURLSession.sharedSession() 

    let task = session.dataTaskWithRequest(request) { data, response, error in 


     if error != nil { 
      println("error=\(error)") 
      return 
     } 

     println("response = \(response)") 

     let responseString = NSString(data: data, encoding: NSUTF8StringEncoding) 
     println("responseString = \(responseString)") 

    } 
    task.resume() 
} 

ma sto ottenendo seguente risposta

response = <NSHTTPURLResponse: 0x1a284b50> { URL: https://sandbox-api.uber.com/v1/requests } { status code: 401, headers { 
"Content-Length" = 75; 
"Content-Type" = "application/json"; 
Date = "Mon, 27 Apr 2015 10:22:01 GMT"; 
Server = nginx; 
"Strict-Transport-Security" = "max-age=31536000; includeSubDomains; preload"; 
"x-uber-app" = "uberex-sandbox"; 
"x-xss-protection" = "1; mode=block"; 
} } 
responseString = Optional({"message":"Invalid OAuth 2.0 credentials provided.","code":"unauthorized"}) 
+0

Date un'occhiata a richiesta con Carlo, forse si SPOTT l'errore. – Yannick

+0

scusa, non ti sto prendendo. –

+1

@QadirHussain Charles è uno strumento di monitoraggio della rete. Rende facile vedere cosa viene inviato indietro e avanti dal simulatore e dal server. – Chackle

risposta

3

Finalmente ho potuto farlo :)

ho cambiato il metodo come qui di seguito e ha funzionato

func callRequestAPI(url:String){ 

    var configuration = NSURLSessionConfiguration.defaultSessionConfiguration() 
    var session = NSURLSession(configuration: configuration) 

    let params:[String: AnyObject] = [ 
     "product_id" : selectedUberProductId, 
     "start_latitude" : start_lat, 
     "start_longitude" : start_lng, 
     "end_latitude" : end_lat, 
     "end_longitude" : end_lng] 



    let request = appDelegate.oauth.request(forURL: NSURL(string:url)!) 
    request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type") 
    request.HTTPMethod = "POST" 
    var err: NSError? 
    request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: NSJSONWritingOptions.allZeros, error: &err) 

    let task = session.dataTaskWithRequest(request) { 
     data, response, error in 

     if let httpResponse = response as? NSHTTPURLResponse { 
      if httpResponse.statusCode != 202 { 
       println("response was not 202: \(response)") 

       return 
      } 
     } 
     if (error != nil) { 
      println("error submitting request: \(error)") 
      return 
     } 

     // handle the data of the successful response here 
     var result = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.allZeros, error: nil) as! NSDictionary 


     println(result) 

     if let request_id: String = result["request_id"] as? String{ 

      println(request_id) 
     } 

     if let driver: String = result["driver"] as? String{ 

      println(driver) 
     } 

     if let eta: Int = result["eta"] as? Int{ 

      println(eta) 
     } 

     if let location: String = result["location"] as? String{ 

      println(location) 
     } 


     if let status: String = result["status"] as? String{ 

      println(status) 
     } 


     if let surge_multiplier: Int = result["surge_multiplier"] as? Int{ 

      println(surge_multiplier) 
     } 

     if let vehicle: String = result["vehicle"] as? String{ 

      println(vehicle) 
     } 

    } 

    task.resume() 

} 

qui è la risposta che ho ricevuto, durante l'analisi è data anche nel mio metodo di cui sopra

{ 
    driver = "<null>"; 
    eta = 15; 
    location = "<null>"; 
    "request_id" = "ea39493d-b718-429f-8710-00a34dcdaa93"; 
    status = processing; 
    "surge_multiplier" = 1; 
    vehicle = "<null>"; 
} 

Enjoy

+0

quali modifiche hai apportato in questo metodo? – Jagdeep

+0

@Jagdeep si prega di vedere il callRequestAPI() nella mia domanda e confrontare con lo stesso nella mia risposta.Vedi le differenze :) –

+0

i in grado di identificare rapidamente due differenze che sono il contenuto param e il contenuto dell'intestazione. è corretto ? – Jagdeep

0

Per utilizzare il token basta seguire il passaggio 5 delle istruzioni nella biblioteca OAuth2, come hai fatto prima di iniziare a provare firmarlo una seconda volta. La richiesta è già stato firmato e ha il portatore Token set up, non c'è più nulla da fare per voi:

let url = NSURL(string: "https://api.uber.com/v1/products?latitude=37.7759792&longitude=-122.41823") 
let req = appDelegate.oauth.request(forURL: url) 

// customize your request, if needed. E.g. for POST: 
req.HTTPMethod = "POST" 

// send the request 
let session = NSURLSession.sharedSession() 
let task = session.dataTaskWithRequest(req) { data, response, error in 
    if nil != error { 
     // something went wrong 
    } 
    else { 
     // check the response and the data 
     // you have just received data with an OAuth2-signed request! 
    } 
} 
task.resume() 
+1

sì, ma devo inviare una richiesta di posta. Quando invio la richiesta POST per l'endpoint di richiesta del driver, il codice è riportato sopra restituisce {"message": "Credenziali OAuth 2.0 non valide fornite", "code": "non autorizzato"} :( –

+0

Ho lo stesso problema. faccio a inviare le credenziali OAuth 2.0? Ho ricevuto il token di accesso ma come usarlo? – Sourav301

+0

Se esegui "appDelegate.oauth.request (forURL: url)", le credenziali sono già incluse nella richiesta. il campione per mostrarti dove puoi personalizzare la tua richiesta – Pascal

1

Aggiornato per Swift 2. Ho usato la stessa configurazione e libreria per Oauth che Qadir descrive nella sua domanda. Ho aggiornato la sua richiesta di lavorare in Swift 2. Spero che questo aiuti gli altri.

uberRequest:

let params:[String:AnyObject] = [ 
     "product_id" : uberProduct, 
     "start_latitude" : userLat, 
     "start_longitude" : userLng, 
     "end_latitude" : barLat, 
     "end_longitude" : barLng] 

    let urlPath = "https://sandbox-api.uber.com/v1/requests" 
    let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate 
    var configuration = NSURLSessionConfiguration.defaultSessionConfiguration() 
    var session = NSURLSession(configuration: configuration) 

    guard let endpoint = NSURL(string: urlPath) else { print("Error creating endpoint");return } 

    let request = appDelegate.oauth.request(forURL: NSURL(string:urlPath)!) 
    request.setValue("application/json; charset=utf-8", forHTTPHeaderField:"Content-Type") 

    request.HTTPBody = try! NSJSONSerialization.dataWithJSONObject(params, options: NSJSONWritingOptions.PrettyPrinted) 

    request.HTTPMethod = "POST" 

    print("Prepare to make request -> \(request)") 

    let task = NSURLSession.sharedSession().dataTaskWithRequest(request){ data, response, error in 
     if error != nil{ 
      print("Error -> \(error)") 
      return 
     } 

     do { 
      let result = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) 

      print("Result -> \(result)") 

     } catch { 
      print("Error -> \(error)") 
     } 
    } 

    task.resume() 

Restituisce:

Result -> Optional(["driver": <null>, "request_id": 5834384c-7283-4fe6-88a7-e74150c6ab30, "surge_multiplier": 1, "location": <null>, "vehicle": <null>, "status": processing, "eta": <null>])