Search code examples
iosnode.jsswiftoauth-2.0uber-api

invalid_grant on OAuth2 request when obtaining access_token from SSO in App


I have an iOS App with an Uber API integration where I use SSO to authenticate the user and then save the accessToken & refreshToken locally on my device. Then I'm calling my server who uses a javascript background function to call the node-uber (https://www.npmjs.com/package/node-uber) library to make a request to Uber. So far, I'm trying to set up the uber client with my 2 local tokens from the SSO login like this:

var uber = new uberClient({
    client_id: '...',
    client_secret: '...',
    server_token: '...',
    name: 'My App',
    sandbox: true, //optional
    access_token: accessToken,
    refresh_token: refreshToken
  });

afterwards I want to call the uber.requests.getEstimatesAsync endpoint like this:

uber.requests.getEstimatesAsync({
      "start_latitude": pickupLocation["lat"],
      "start_longitude": pickupLocation["lng"],
      "end_latitude": dropoffLocation["lat"],
      "end_longitude": dropoffLocation["lng"]
      })
      .then(function(res) { 
        console.log(JSON.stringify(res)); 
      })
      .error(function(err) { 
        console.error(err); 
      });
})

Though every time I get an "invalid_grant" error 400 while doing this. Did I make a mistake authenticating myself or setting up the Uber client wrong? Is it even possible to use my SSO accessToken & refreshToken then on the uber client, which does a OAuth2 authentification? I thought that both access and refresh token should probably be the same what Uber sends back to be for SSO & OAuth2. I'm using a Developer account for doing this, therefore I should actually have all the required permissions for the request endpoint, but I also obtained them previously in the App correctly.

This thread on the official uber documentation explains potential reasons but I guess they don't really apply to my case, do they? https://developer.uber.com/docs/riders/guides/authentication/introduction#common-problems-and-solutions

Any security expert here who can help? Best regards, Matt

P.S.: I also posted this question on the Uber library I'm using for making those requests, but nobody seems to be able to help me there so far. https://github.com/shernshiou/node-uber/issues/70

Edit: The following picture shows my authentication setup so far:

enter image description here


Solution

  • I found a solution. I think was a problem with the library itself. Because once I made the request with http with the "request" library (https://github.com/request/request) it worked. Include for that at the top of your code:

    var request = require('request');
    

    Both OAuth2 and SSO accessToken worked. You should give the method a pickupLocation with latitude and longitude and your obtained accessToken from Uber like this:

    function getAllAvailableUberProducts(pickupLocation, accessToken){
        var lat = pickupLocation["lat"].toString();
        var lng = pickupLocation["lng"].toString();
    
        var options = {
            uri: "https://api.uber.com/v1.2/products?latitude="+lat+"&longitude="+lng,
            method: 'GET',
            headers: {
                "Authorization": "Bearer " + accessToken,
                "Accept-Language": "en_US",
                "Content-Type": "application/json"
            }
        };
    
        request(options, function (error, response, body) {
            if (!error && response.statusCode == 200) {
                console.log(JSON.parse(body).products);
            } else {
                console.log(error);
            }
        });
    }
    

    I hope this helps someone.