优步无效的OAuth 2.0凭据提供Uber身份validation在iOS Swift中

我在我的iOS(Swift)应用程序中实现Uber的Request Endpoint 。 Request API / Endpoint需要使用应用程序的用户身份validation,这里是文档 。

为此,我使用这个Oauth2.0库

我做的是

  1. 在给定的安装说明的帮助下,成功地将库集成到我的项目(xCode)中。

  2. 在我的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. 在我的方法didFinishLaunchingWithOptions的Appdelegate

      oauth = OAuth2CodeGrant(settings: uber_OAuth_Settings) oauth.viewTitle = "Uber Login Service" // optional oauth.verbose = true // For Logs 
  4. 不要忘了注册urlschemeie( "redirect_uris": ["jamesappv2://oauth/callback"]

转到你的应用程序的目标 – >信息标签 – >urltypes – >点击(+),附加的图像

在这里输入图像说明

  1. 在AppDelegate中添加下面给出的方法并处理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. 现在在我的viewController我喜欢这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)") } } 

这是我的debugging日志,我得到有效的回应:

  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] 

注意我正在获取有效的access_token

在这里,我卡住了

根据DOCs在STEP4 *使用pandas标记

将Authorization头部响应中返回的access_token与typesBearer进行传递,代表用户发出请求。*

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

我没有明白这一点。 我应该如何通过types持有人的标题中传递access_token? 我做了如下

 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() } 

但我得到以下回应

 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"}) 

最后我做到了:)

我改变了下面的方法,它工作

 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() } 

这里是我得到的回应,parsing也在我的上述方法给出

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

请享用

更新了Swift 2.我使用了与Qadir在他的问题中描述的oauth相同的设置和库。 我更新了他的请求在Swift 2中工作。希望这可以帮助其他人。

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() 

它返回:

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

要使用该令牌,请按照OAuth2库中的说明的步骤5进行操作,就像在开始尝试再次尝试自己签名之前一样。 请求已经被签名,并且已经build立了不记名令牌,没有什么可以为你做的了:

 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. Eg 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()