优步无效的OAuth 2.0凭据提供Uber身份validation在iOS Swift中
我在我的iOS(Swift)应用程序中实现Uber的Request Endpoint 。 Request API / Endpoint需要使用应用程序的用户身份validation,这里是文档 。
为此,我使用这个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
的Appdelegateoauth = OAuth2CodeGrant(settings: uber_OAuth_Settings) oauth.viewTitle = "Uber Login Service" // optional oauth.verbose = true // For Logs
-
不要忘了注册urlschemeie(
"redirect_uris": ["jamesappv2://oauth/callback"]
)
转到你的应用程序的目标 – >信息标签 – >urltypes – >点击(+),附加的图像
-
在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 }
-
现在在我的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()