shopify - nodejs - get permanent token fails - node.js

I have written an application that talks with the shopify API. I manage to get the temporary code from shopify and redirect back to my app where I store the code to later exchange for the permanent token.
According to the docs all I need to do is then send a POST request to https://{shop}.myshopify.com/admin/oauth/access_token with the client_id, client_secret and code is the body of the request.
I am using the request module to send the request and have it set up to send the request as such:
var options = {
method: POST,
url: https://my-develop-shop.myshopify.com/admin/oauth/access_token,
json: true
};
var _body = {
"client_id": config.get('SHOP_ID'),
"client_secret": config.get('SHOP_SECRET'),
"code": tempCode
}
_body = JSON.stringify(_body);
options.body = _body;
request(options, callback);
However when I send the request it always returns with : error_description: 'Could not find Shopify API application with api_key ' }
The app is installed successfully on the client's shop, so why would this error be returned?
Is there a special header that shopify expects? The docs are so vague.
Why does it not authenticate?

Well I cheated and used the shopify-node-api package. There I just use the exchange_temporary_token method. This api also handles throttling so it's a decent investment in the time you might spend incorporating it.

Related

unauthorized_client error getting access_token in nodejs (googleapis)

I've spent a lot of hours with this and could not find out what I am doing wrong with this.
I have a client-server web app (javascript in client, node in server). In the server I use googleapis.
I want the user to authenticate with Google Oauth2 in the Client, and then, send the authorization code to the server, get the access_token (or refresh_token), and then make some calls to google APIs (by now it will create or delete calendars to the user's account).
I get an error when trying to get my access_token in the back end.
In the front end I have this call:
var SCOPE_STRING = "https://www.googleapis.com/auth/calendar.app.created";
if(nouUsuari.hasGrantedScopes(SCOPE_STRING)) {
console.log("hasGrantedScopes.");
} else {
nouUsuari.grantOfflineAccess({
scope: SCOPE_STRING
})
.then(function(resp){
var authCode = resp.code;
//I send here authCode to the backEnd
self.guardarTokens(authCode);
})
}
In the back end, I'm stuck at getting my acces_token, whith this call:
var response = await self.oAuth2Client.getToken(authCodeFromFrontEnd)
I always get the following error:
{
"error": "unauthorized_client",
"error_description": "Unauthorized"
}
Any help will be really appreciated as I don't know how to follow with this.
Thanks a lot!!!!

Not getting data of GITHUB api using npm module sync-request

I am trying to get data of below url using sync-request module.
https://api.github.com/repos/rethinkdb/rethinkdb/stargazers
I get the data when i call it in browser or through postman.
But i am getting 403 forbidden error when calling it using sync-request in my node api.
My code looks like this.
var request = require("sync-request");
var response = request('GET', 'https://api.github.com/repos/rethinkdb/rethinkdb/stargazers', {
headers: {},
json: true
});
I am able to fetch data of many other api's but not this one. Please help.
Response body already contains the explanation:
Request forbidden by administrative rules. Please make sure your request has a User-Agent header (http://developer.github.com/v3/#user-agent-required). Check https://developer.github.com for other possible causes.
It will work like:
var response = request('GET', 'https://api.github.com/repos/rethinkdb/rethinkdb/stargazers', {
headers: { 'User-Agent': 'Request' },
json: true
});
The use of sync-request is strongly discouraged because synchronousness is achieved via a hack and may block the process for a long time.
For sequential execution request-promise can be used together with async..await.
Try to use an access token along with the GitHub API call
like this
[https://api.github.com/repos/rethinkdb/rethinkdb/stargazers?access_token=f33d1f112b7883456c990028539a22143243aea9]
As you say the API works in the browser it should not be an issue.
When you use too many calls through the GitHub API they they give the following message
{
"message": "API rate limit exceeded for 192.248.24.50. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)",
"documentation_url": "https://developer.github.com/v3/#rate-limiting"
}
To overcome this issue you can use an access token using an access token you can to access the private repositories in your account as well .
Here is the link for to get an access token [https://github.com/settings/developers]

How to authorize for Amazon's Alexa API?

I want to send a request to this Amazon Alexa API.
That page contains the last 50 activities I made with my Amazon Echo. The page returns JSON. Before you can request that page, you need to authorize your account, so the proper cookies are set in your browser.
If I do something simple as:
const rp = require("request-promise");
const options = {
method: "GET",
uri: "https://alexa.amazon.com/api/activities?startTime=&size=50&offset=-1",
json: true
};
rp(options).then(function(data) {
console.log(data);
}).catch(function(err) {
console.log(err);
});
I can send a GET request to that URL. This works fine, except Amazon has no idea it's me who's sending the request, because I haven't authorized my NodeJS application.
I've successfully copied ~10 cookies from my regular browser into an incognito tab and authorized that way, so I know copying the cookies will work. After adding them all using tough-cookie, it didn't work, unfortunately. I still got redirected to the signin page (according to the error response).
How do I authorize for this API, so I can send my requests?
I have been looking for a solution for this too. The best idea I have is to use account linking, but I haven't try it yet. Looks like ASK-CLI has interface for this also, but I can't figure it out how to use it (what is that URL?). For linking account to 3rd party server is not easy, but link it back to Amazon for the json API should not be that complicated.

Connect NodeJS as client to third party service that uses session data

I am developing a website in Node.JS / Express, and have until now used JWTs to store authentication data.
To summarize, I have an AngularJS app which calls a REST service on Node, and for authentication the user POSTs username and data to the server and gets a JWT containing the username and expiration, which then gets sent along with every request which requires authentication.
Now, though, I need to be able to connect to a third party service (which is a REST service that runs on Delphi) which uses sessions to save authentication data instead.
Using Fiddler, I can see that the service, when used in another implementation (third party) responds with JSON authentication data. In all subsequent requests, the client sends a cookie called dsessionid, although it doesn't appear in the "response cookies" in the previous response.
My question is: how do I take that dsessionid cookie in my NodeJS app and put it in my JWT so I can send it to my actual client?
I managed to solve my problem by getting the session ID in the "Pragma" header of the response (I don't know if the header is something "default" for Delphi applications or if it was specific to this application, I had to look through Fiddler entries to find out what header had the data) and then using a custom cookie jar with the request module to put the session ID in the cookies of subsequent requests.
const request = require('request-promise-native')
return request.get({
url: 'http://example.com:20202/auth',
resolveWithFullResponse: true
})
.then(res => {
return res.headers['pragma']
})
.then(sid => {
let j = request.jar()
j.setCookie(request.cookie('sessionid=' + sid), 'http://example.com')
return request.get({
url:'http://example.com:20202/fetchData',
resolveWithFullResponse: true,
jar: j
})
Hope this helps somebody.

redirect to another app with session token (jwt) in AngularJS and NodeJS

I have a startup module in angularjs. This module is just to login and have public information (login, prices, newsletter...). I have many roles and for each role, i have an app (angular module). I made this architecture because i have complex module for each role and it was impossible to put all roles in one module.
So, for login, i use jsonwebtoken in node like this :
var token = jwt.sign(user, config.secureToken, { expiresInMinutes: 20*5});
res.json({ token: token, user: user });
It works perfectly. I can login into my app. After that, i have to propose a list of roles to redirect to the right module.
In angular, I have AuthHttp service that adds security headers (with token) to call rest service with $http.
How can i redirect to 'mydomain:port/anotherModule' with $location or $http ?
With this code in nodejs :
app.get('/secondModule', expressJwt({secret: config.secureToken}), function (req, res) {
res.render('restricted/secondModule/index.html');
});
NodeJs sends an html code in response and does'nt redirect...
And if i do this in my angular controller :
location.href = route;
i have this result on nodejs console :
Error: No Authorization header was found
I am not sure about the libraries you are using, but issue seems that you are loosing the token because you navigate to a altogether new page.
Based on your auth library you need to pass the token that you get after auth from one page to another.
The options here are to either use browser sessionStorage or querystring to pass the token along and at it back to the http header collection on the new page (module)
This is an old post but I recently took a long time to figure this out. I may be wrong but I believe nodeJS/expressJS can't read the token from the session storage. I believe you will need to pass the token via the request header using AngularJS.
This depends on the front end that you are using. For me, I am using AngularJS and I have to do something like this.
angular.module('AngularApp').factory('authFactory',
function($window){ //the window object will be able to access the token
var auth = {};
auth.saveToken = function(token){
$window.localStorage['token_name'] = token; //saving the token
}
auth.getToken = function(){
return $window.localStorage['token_name']; //retrieving the token
}
return auth;
}
.service('authInterceptor, function(authFactory){
return { headers: {Authorization: 'Bearer "+ authFactory.getToken()}
} //the last line gets the retrieved token and put it in req.header
Then, you just need to include 'authInterceptor' in all the http methods when you communicate with the backend. This way, nodeJS will be able to pick up the token.
You can see the Authorization field in req.header if you use the chrome developer tool and look at the Network tab. Hope this helps.

Resources