invalid_grant on OAuth2 request when obtaining access_token from SSO in App - ios

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:

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.

Related

Amazon sp-api Authorisation Workflow Issue

Following the SP-API developer guide, I created an app to be able to access SP-API. The app is in published state now and we tried the authorisation workflow as per the amazon guide steps:
https://github.com/amzn/selling-partner-api-docs/blob/main/guides/en-US/developer-guide/SellingPartnerApiDeveloperGuide.md#amazon-seller-central-partner-network-authorization-workflow
We are using the website authorisation workflow, the steps 1-3 work as per the guide,
Step 1. Initiate the authorization from the Amazon Seller Central Partner Network.
Step 2. The selling partner consents to authorize your application, we authorise the app from seller Central and start the process, this url loads
https://sellercentral.amazon.com/apps/authorize/consent?application_id=amzn1.sp.solution.6cf699bd-f89a-4afd-b64e-7d21351aaaaa
Step 3. The selling partner signs into your website, we are redirected to the website login and that is done, then we get the amazon state and partner id as part of the url:
https://dashboard.aaa.com/api/amzn/login?amazon_callback_uri=https%3A%2F%2Fsellercentral.amazon.com%2Fapps%2Fauthorize%2Fconfirm%2Famzn1.sp.solution.6cf699bd-f89a-4afd-b64e-7d21351aaaa&amazon_state=MTY0MzgzMjI2NzU2OADvv71PY8KzGA0Iaih1Nzjvv71bHNqRGO-_ve-_ve-_ve-_vRnvv70a77-9eTF577-9Ee-_vRDvv70W77-9FEnvv73vv71ueO-_vR7vv73vv70PYu-_vUJd77-9B--_vTxF77-977-9f--_vQ%3D%3D&selling_partner_id=A2079RJZNKAAAA
Step 4. Amazon sends you the authorization information - Then we are redirected back to Seller Central -
https://sellercentral.amazon.com/apps/authorize/confirm/amzn1.sp.solution.6cf699bd-f89a-4afd-b64e-7d21351aaaa?state=1d477f90edfa493a1d15&amazon_state=MTY0MzgzMjI2NzU2OADvv71PY8KzGA0Iaih1Nzjvv71bHNqRGO-_ve-_ve-_ve-_vRnvv70a77-9eTF577-9Ee-_vRDvv70W77-9FEnvv73vv71ueO-_vR7vv73vv70PYu-_vUJd77-9B--_vTxF77-977-9f--_vQ==&selling_partner_id=A2079RJZNKAAAA&redirect_uri=https://dashboard.aaa.com/api/amzn/redirect
We are getting the sp_oauth_code in the url and tried using that to request for refresh token via POSTMAN request but unable to proceed to request the token from amazon oauth service.
We are getting error 400 as response, this is request format from the postman code section:
var axios = require('axios');
var qs = require('qs');
var data = qs.stringify({
'grant_type': 'authorization_code',
'code': 'ANnGBdMPnXAlrMyfUdwaaa',
'client_id': 'amzn1.application-oa2-client.cf71c857f2fd4f2c968851619bdaaaaa',
'client_secret': 'bba375434456e9917fcd5539c4324cc0e3182cccb9f1694ce3c63bee4f1aaaaa',
'redirect_uri': 'https://dashboard.aaa.com/api/amzn/redirect'
});
var config = {
method: 'post',
url: 'https://api.amazon.com/auth/o2/token',
headers: { },
data : data
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
We are sending data as x-www-form-urlencoded as Json in the POST request.
Any pointers on what we could differently or check for any missing params - any inputs on what to look for would be greatly appreciated.
The SP-API documentation is a little vague on this as it says you should include the grant type, code, seller id and secret as query parameters which by definition means within the url.
You actually need to add them to the body of the POST request.
This is an interesting discussion which revealed the above to me: https://github.com/amzn/selling-partner-api-docs/issues/79
Hope it helps.

How to create SendBird user with SendBird Platform API and Request node library

We are building a react-native chat app. We are implementing a back end authentication solution on google Firebase. The creation of a new user in Firebase Auth triggers a cloud function which should create a new SendBird user with an access token. The access token will be stored in Cloud Firestore, ready for retrieval the next time the user logs in.
We are having trouble implementing the POST request that creates the new user via the platform API. We are using the Request library for node.js. We are able to reach the API endpoint, but the following object is returned: { message: 'SendBird API Endpoint.', error: true }. There is no indication of what the error may be.
This happens when sending the request to the base url. When we send the request to /users or /v3/users, we receive a 403 error.
Any indication as to what may be causing this problem would be greatly appreciated.
Below is the cloud function index.js code
const functions = require('firebase-functions');
const admin = require("firebase-admin");
const request = require('request');
admin.initializeApp();
exports.handleNewUser = functions.auth.user().onCreate((user) => {
var newUserRequestBody = {
"user_id": user.email,
"nickname": user.email,
"profile_url": "",
"issue_access_token": true,
}
request.post({
headers: {
'Content-Type': 'application/json, charset=utf8',
'Api-Token': // API Token
},
url: 'https://api-{application_id}.sendbird.com',
form: newUserRequestBody
}, function(error, response, body){
if (!error && response.statusCode === 200) {
const info = JSON.parse(body);
console.log("request successful");
console.log(response.statusCode);
console.log(info);
}
else{
console.log("request unsuccessful");
console.log(response.statusCode);
console.log(error);
}
});
return null;
});
Did you try with full path of end point to url: (including /v3/users)?
Or you may need to use "baseUrl" like below?
https://github.com/request/request#requestoptions-callback
Also, you need to make sure that you correctly used {application_id} value and {API Token} value.
You can double check this from your dashboard of SendBird.
http://dashboard.sendbird.com > Log in with your ID > select your APP.
There is a section named "App credentials" in "Overview" menu.
You can double check your API-request URL and API-Token value from there.

Can't hit Google plus api after oauth with Firebase

2 hours trying to get this to work and I can't. Firebase authenticates the user just fine, but then it can't fetch anything from the Google Plus API.
The error you will get:
{
domain: "global"
location: "Authorization"
locationType: "header"
message: "Invalid Credentials"
reason: "authError"
}
The code is this:
Auth.$authWithOAuthPopup(provider, {
scope: ['profile', 'email']
}).then(function(authData) {
console.log(authData.token);
gapi.client.setApiKey('<APIKEY>');
gapi.client.load('plus','v1', function(){
var request = gapi.client.plus.people.get({
'userId': 'me'
});
request.execute(function(resp) {
console.log('Retrieved profile for:' + resp.displayName);
debugger;
});
});
}, showError);
It must have something to do with Firebase making the call on our behalf. Because this codepen, in which we do our own authentication, works fine:
http://codepen.io/morgs32/pen/KVgzBw
Don't forget to set clientId and apiKey in the codepen.
If you can figure this one out you're gonna get gold on christmas.
You're trying to use authData.token to access Google. But authData.token is a JWT token for accessing Firebase.
To access Google, you should use authData.google.accessToken.
Also see this page in the Firebase documentation on using the Google provider.

Shopify: Problems Getting OAuth Access Token

I've retrieved the authorization code in Step 1 of OAuth without a problem, but for the life of me I can't complete a post to get the access token. I always get the same error:
content: "{"error":"invalid_request","error_description":"Could not find Shopify API appli... (length: 103)"
Here's what my code looks like...Meteor.http.post is a standard post request. I've tried all sorts of combinations without any luck. I'm developing on localhost:
var url = 'https://' + shopName + '/admin/oauth/access_token';
var data = { client_id: apiKey, client_secret: secret, code: code };
Meteor.http.post(url, data,
function(error, result) {
debugger;
});
Meteor.post is a standard server-side post request documented here. I've tried params (like the Node Wrapper), an array (like PHP) and a combination of other things. I have no idea.
Is it because I'm developing on localhost and server calls require https now? Is my post data structure wrong?
Any other ideas what I'm doing wrong?
I know you said you tried params but placing the params in as data like that wouldn't work. Try this..
var url = 'https://' + shopName + '/admin/oauth/access_token';
var data = { client_id: apiKey, client_secret: secret, code: code };
Meteor.http.post(url, {params:data},
function(error, result) {
debugger;
});

Foursquare API, oauth, HTTP 301

i'm playing with the foursquare api in nodejs.
I follow the steps described here (Web server application)
but in the last step, when i'd get the authorization_code i get an HTTP 301 pointing to the same url which was requested.
I don't know why.
do i miss something?
Have you looked at connect-auth? It is a pretty good library and it also supports foursquare.
To install:
npm install oauth connect-auth
To use try:
var foursquareConsumerKey = "";
var foursquareConsumerSecret = "";
app.get ('/auth/foursquare', function(req, res, params) {
req.authenticate(['foursquare'], function(error, authenticated) {
res.writeHead(200, {'Content-Type': 'text/html'})
if( authenticated ) {
res.end("<html><h1>Hello foursquare user:" + JSON.stringify( req.getAuthDetails().user ) + ".</h1></html>")
}
else {
res.end("<html><h1>Foursquare authentication failed :( </h1></html>")
}
});
})
I think your code must look something like this, but I have not tried it yet, because I don't have foursquare account.
I started implementing my own solution based on the new 4sq api (v2) and oauth2
https://github.com/yikulju/Foursquare-on-node

Resources