我正在我的iOS(Swift)应用中实现Uber的请求端点。Request API / Endpoint要求用户通过应用进行身份验证,这是doc。
为此,我正在使用此Oauth2.0库
我所做的是
借助给定的安装说明,成功地将库集成到我的项目(xCode)中。
在我的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!
didFinishLaunchingWithOptions
oauth = OAuth2CodeGrant(settings: uber_OAuth_Settings) oauth.viewTitle = "Uber Login Service" // optional oauth.verbose = true // For Logs
"redirect_uris": ["jamesappv2://oauth/callback"]
转到应用程序的目标->信息选项卡->网址类型->单击(+),附加图片
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 }
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)") } }
这是我的调试日志,我得到有效的响应:
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
我被困在这里
按照DOC在STEP4中所说的*使用承载令牌
将响应中返回的access_token传递给类型为Bearer的Authorization标头,以代表用户发出请求。*
curl -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' 'https://api.uber.com/v1/products?latitude=37.7759792&longitude=-122.41823'
我不明白这一点。我应该如何在Bearer中传递类型为Bearer的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() }
这是我得到的响应,我上面的方法也给出了解析
{ driver = "<null>"; eta = 15; location = "<null>"; "request_id" = "ea39493d-b718-429f-8710-00a34dcdaa93"; status = processing; "surge_multiplier" = 1; vehicle = "<null>"; }
请享用