I want to access the WS REST API in node.js. I have the oauth_consumer_key and the oauth_token and the API end point. The oauth_signature_method is HMAC-SHA1.
How to send the OAuth request in Node?
Is there a module/library to generate the request headers? What I expect is a function like:
var httprequest = createRequest(url, method, consumer_key, token);
UPDATE 10/14/2012. Adding the solution.
I'm using the code below.
var OAuth = require('oauth').OAuth;
consumer = new OAuth('http://term.ie/oauth/example/request_token.php',
'http://term.ie/oauth/example/access_token.php',
'key', 'secret', '1.0',
null, 'HMAC-SHA1');
// Get the request token
consumer.getOAuthRequestToken(function(err, oauth_token, oauth_token_secret, results ){
console.log('==>Get the request token');
console.log(arguments);
});
// Get the authorized access_token with the un-authorized one.
consumer.getOAuthAccessToken('requestkey', 'requestsecret', function (err, oauth_token, oauth_token_secret, results){
console.log('==>Get the access token');
console.log(arguments);
});
// Access the protected resource with access token
var url='http://term.ie/oauth/example/echo_api.php?method=foo&bar=baz';
consumer.get(url,'accesskey', 'accesssecret', function (err, data, response){
console.log('==>Access the protected resource with access token');
console.log(err);
console.log(data);
});
We use https://github.com/ciaranj/node-oauth
This is more of a complete node twitter package that seems streamlined and useful.
https://npmjs.org/package/twitter
Related
I am working on twitter oauth through chrome extension. I need to get oauth_token to authenticate the user. I am referring to https://developer.twitter.com/en/docs/tutorials/authenticating-with-twitter-api-for-enterprise/oauth1-0a-and-user-access-tokens. Can you guide me to send post request for my oauth token in javascript ?
You can refer to the above link for steps but I need to implement my post request in background.js instead to sending it in postman. I need my ext to create new request for each login, which for create different oauth token for each session.
I want to create a post request with following requirements:
URL-'https://api.twitter.com/oauth/request_token'
query- 'oauth_callback':'oob'
auth- we want to provide consumer key and consumer secret here
headers- 'Content-Type':'application/json'
This is a screenshot of postman. On implementing this, the post request returns oauth token and secret.
Please help me out on this.
import oauth from 'oauth';
const oauthCallback = process.env.FRONTEND_URL;
const CONSUMER_KEY = process.env.CONSUMER_KEY;
const CONSUMER_SECRET = process.env.CONSUMER_SECRET;
const _oauth = new oauth.OAuth(
'https://api.twitter.com/oauth/request_token',
'https://api.twitter.com/oauth/access_token',
CONSUMER_KEY, // consumer key
CONSUMER_SECRET, // consumer secret
'1.0',
oauthCallback,
'HMAC-SHA1',
);
export const getOAuthRequestToken = () => {
return new Promise((resolve, reject) => {
_oauth.getOAuthRequestToken((error, oauth_token, oauth_token_secret,
results) => {
if (error) {
reject(error);
} else {
console.log({ oauth_token, oauth_token_secret, results });
resolve({ oauth_token, oauth_token_secret, results });
}
});
});
};
Try this method in your backend to get the OAuth token and secret. It helped in my case, maybe it can work for you as well.
Use this to install oauth lib
npm i oauth
Refer for more info:
https://javascript.works-hub.com/learn/building-with-twitter-authentication-35ad6
I'm relatively new to Node.js and I'm creating a server that will accept a POST request from a mobile app whose body contains a credential that will then be verified via a GET to another server. If the GET response validates the credential, then the UID is extracted and a call is made to the firebase admin SDK to create a custom token. Here is a snippet of the code and two functions that are called to (a) validate the credential and (b) generate the custom token.
//Listen for app to POST Credential
app.post('/', function(request, response) {
console.log('Request Body: ',request.body);
var Credential = request.body;
//Validate Credential
validateCredential(Credential)
//Get Authorization Token
getToken(userID)
//Return Token for POST Response
response.set('Content-Type','Text');
response.end(firebaseAuthToken);
});
//Create listener for POST function
app.listen(port, function() {
console.log('AuthServer is running and listening on port '+port);
});
//Function to Validate Credential
async function validateCredential(crdntl) {
//Call Service to validate Credential received
axios({
method: 'get',
url: 'https://.....',
})
.then(function(response) {
...check credential validation data
})
.catch(function (error) {
console.log('ERROR: Unable to Validate Credential');
//Unable to create Validate Credential so return error message for POST response
return ('ERROR1');
});
}
async function getToken(uid) {
admin.auth().createCustomToken(uid)
.then(function(customToken) {
var AuthToken = customToken;
var decoded = jwt.decode(AuthToken);
console.log('Decoded Token: '+'\n',decoded);
//Return Authorization Token for POST response
return (AuthToken);
})
.catch(function(error) {
console.log('ERROR: Unable to Create Custom Token', error);
//Unable to create Token so return error message for POST response
return ('ERROR2');
});
}
}
I need the result of the validateCredential function to be returned and its result passed to the getToken function and its result returned so that the POST response can be sent. I know these function are async and I can chain them with callbacks or promises.
The real issue is how to make the POST response wait for a callback from the getToken function as the ultimate goal is to pass the custom token back to the mobile app in the body of the POST response.
Any help would be appreciated.
Your validateCredential and getToken functions are already async which in turn returns promise, To wait in POST function for these functions to send response, You have to make POST function async and then use await keyword while calling those 2 functions, when you use await function execution waits until function response which is Promise resolves, Here is sample code.
//Listen for app to POST Credential
app.post('/', async function(request, response) {
console.log('Request Body: ',request.body);
var Credential = request.body;
//Validate Credential
var userId = await validateCredential(Credential) //Waits until userId comes
//Get Authorization Token
var firebaseAuthToken = await getToken(userID) //waits until Token comes
//Return Token for POST Response
response.set('Content-Type','Text');
response.end(firebaseAuthToken);
});
I am writing a Node.js client for a REST API that uses OAuth2. I am using Bluebird and promises (and sending the access token in the header) and I was wondering when would be a good time to check if the access token is already granted (exists) or still valid (not expired).
So far, I have come up with this:
'use strict';
var Bluebird = require('bluebird');
var request = Bluebird.promisifyAll(require('request'), { multiArgs: true });
var Oauth = require('oauth');
var OAuth2 = OAuth.OAuth2;
var _ = require('lodash');
function Client(options) {
this.options = _.assign({
url: '<API URL>',
oauth2Url: 'oauth2/token',
apiVersion: process.env.apiVersion,
consumerKey: process.env.consumerKey,
consumerSecret: process.env.consumerSecret
}, options);
if (!this.options.url) {
throw new Error('Missing client url.');
}
...
if (!this.options.consumerSecret) {
throw new Error('Missing consumer secret.');
}
if(!this.access_token){
var oauth2 = new OAuth2(
this.options.consumerKey,
this.options.consumerSecret,
this.options.url + this.options.version,
null,
this.options.oauth2Url,
null);
oauth2.getOAuthAccessToken(
'',
{'grant_type':'client_credentials'},
function (e, access_token, refresh_token, results){
this.access_token = access_token;
this.refresh_token = refresh_token;
done();
});
}
}
Client.prototype.queryApi = function (options, callback) {
return request.postAsync({
headers: {
Authorization: 'Bearer ' + access_token
},
url: this.options.url + this.options.apiVersion,
body: JSON.stringify(options)}).
then(function (result) {
var json = JSON.parse(result[1]);
if (_.isFunction(callback)) {
callback(null, json);
}
return json;
}).
catch(function (err) {
if (_.isFunction(callback)) {
callback(err);
return;
}
throw err;
});
};
module.exports = Client;
I am new to both Oauth/Oauth2 and Node.js and I was just wondering if I am checking for the access token in the right place and how/where can I also check if it expired or not. Thanks!
First of all there is two way to check whether access token is expired or not
By knowing token_expiration value from your oauth app.In this case you need to keep task running on your app that will determine wheter access_token is expired or not.(Not recommended way of handling access token)
Handle the response from Authorization server stating that your acces token has been expired.In this case you need to get new access token by presenting refresh token.
You can write 'tokenPersistanceFunction' that will be called when your oauth values(access_token,refresh_token) are updated.
I have modified your code to reflect these changes
function tokenPersistanceFunction(updatedOauth){
// Here you will get Updated Oauth values
// Save these to DB
return saveAccessToken(updatedOauth.access_token, updatedOauth.refresh_token);
}
Client.prototype.queryApi = function (options, tokenPersistanceFunction, callback) {
return request.postAsync({
headers: {
Authorization: 'Bearer ' + access_token
},
url: this.options.url + this.options.apiVersion,
body: JSON.stringify(options)}).
then(function (result) {
// You have some indication from your oauth server, that your access_token is expired.
// You can check your response here to know whether access_token is expired or not.
// If access_token is expired, Make request to refresh access token.
// In your case
if(AccessTokenIsExpired){
// Function that will make request to refresh access_token by presenting refresh_token
return <functionThatRefreshesAccessToken>( refreshAccessTokenOptions,tokenPersistanceFunction)
.then(function(result){
//Extract access_token, refresh_token from response
// call 'tokenPersistanceFunction' to store these token in your DB.
return tokenPersistanceFunction(updatedOauth);
})
.then(function(savedOauthTokensSuccess){
// Now you have the updated Oauth tokens, you can make request to get resource
// this call will return you the actual response.
return queryApi(options, tokenPersistanceFunction, callback);
})
}else{
var json = JSON.parse(result[1]);
if (_.isFunction(callback)) {
callback(null, json);
}
return json;
}
}).
catch(function (err) {
if (_.isFunction(callback)) {
callback(err);
return;
}
throw err;
});
};
I'm building an app with node.js and express.js. I'm using the node-oauth module to connect to yahoo so I can make get requests to the api. I keep getting the error below
{ statusCode: 401,
data: '{"error":{"#lang":"en-US",
"#uri":"http://yahoo.com",
"description":"Not Authorized - Either YT cookies or a valid OAuth token must be passed for authorization","detail":"Not Authorized - Either YT cookies or a valid OAuth token must be passed for authorization"}}' }
After trying for a while to figure out my problem, I'm asking the community to check out my code and see what I am doing wrong. Code included below.
"use strict";
// declare libraries
var express = require('express');
var router = express.Router();
var OAuth = require('OAuth');
// set yahoo key and secret
var yahooKey = '*****************************************************';
var yahooSecret = '*********************************';
var oauth2 = new OAuth.OAuth2(
yahooKey,
yahooSecret,
'https://api.login.yahoo.com/',
'oauth2/request_auth',
'oauth2/get_token',
null
);
router.get('/', function(req, res, next) {
var access_token = oauth2.getOAuthAccessToken(
'',
{'grant_type':'authorization_code', 'redirect_uri':'http://www.domain.com'},
function (e, access_token, refresh_token, results) {
// console.log(e);
// done();
});
// console.log(oauth);
oauth2.get(
'https://social.yahooapis.com/v1/user/circuitjump/profile?format=json',
access_token,
function (error, data, response){
if (error) {
console.error(error);
}
// data = JSON.parse(data);
// console.log(JSON.stringify(data, 0, 2));
// console.log(response);
});
res.render('index', { title: 'Express' });
});
// export route
module.exports = router;
Any help is greatly appreciated. My brain is fried ...
You seem to be missing some steps. I would direct you first to this guide:
https://developer.yahoo.com/oauth2/guide/flows_authcode/
First, from your starting path at '/', you need to redirect (302) the user to an authorization page (Step 2 of yahoo's guide). The oauth lib has a helper for you to generate the correct URL:
var location = oauth2.getAuthorizeUrl({
client_id: yahooKey,
redirect_uri: 'https://yourservice.com/oauth2/yahoo/callback',
response_type: 'code'
});
res.redirect(location);
What you just did there is you redirected the user's browser to yahoo's authorization page, where the user gets a dialog asking if they want to allow your service XYZ access to do stuff on the user's behalf. Upon clicking "Allow", yahoo will redirect the browser to your callback url (Step 3 of yahoo's guide), providing you with an authorization code in the query params. In this example you have hooked up at /oauth2/yahoo/callback
You can set that up like so (Step 4 of yahoo's guide):
router.get('/oauth2/yahoo/callback', function(req, res) {
// Aha now I have an authorization code!
var code = req.query.code;
oauth2.getOAuthAccessToken(
code,
{
'grant_type': 'authorization_code',
'redirect_uri': 'oob'
},
function(e, access_token, refresh_token, results) {
console.log('Now I have a token', access_token, 'that I can use to call Yahoo APIs!');
res.end();
});
});
I hope all of that makes some sense. I'll leave it as an exercise for you to figure out the refresh token (step 5). If you make it this far, that part should be easy :)
Edit
It looks like Yahoo also requires you to send your key and secret in a Authorization Basic header. You can generate this header and tell the oauth2 module to include it like so:
var encoded = new Buffer(yahooKey+":"+yahooSecret).toString('base64')
var authHeader = "Basic " + encoded;
var oauth2 = new OAuth.OAuth2(
yahooKey,
yahooSecret,
'https://api.login.yahoo.com/',
'oauth2/request_auth',
'oauth2/get_token',
{ Authorization: "Basic " + authHeader}
);
From today I'm not able to retrieve my Google+ activities by placing a GET request to this url:
https://www.googleapis.com/plus/v1/people/me/activities/public?key={API_KEY}
I'm getting a 401 error. So I tried to sign the request using the node.js oauth2 library, including a pre-generated user token, but I'm getting the same error. The js code for my test script is:
var OAuth2 = require('oauth').OAuth2,
GOOGLEPLUS_APP_ID = {APP_ID},
GOOGLEPLUS_APP_SECRET = {APP_SECRET},
accessToken = {USER_TOKEN};
var _oauth2 = new OAuth2(GOOGLEPLUS_APP_ID, GOOGLEPLUS_APP_SECRET, '',
'https://accounts.google.com/o/oauth2/auth',
'https://accounts.google.com/o/oauth2/token');
_oauth2.get('https://www.googleapis.com/plus/v1/people/me/activities/public?key={API_KEY}',
accessToken, function (err, body, res) {
if (err) {
console.log('error:');
console.log(err);
}
else console.log(body);
});
I placed the same request to get the basic user info (url: https://www.googleapis.com/oauth2/v1/userinfo) and works OK.
Can you please assist me with this?
Thank you.
If you have the access token already you should be able to use {?|&}access_token=X to get the result, example below.
var accessToken = 'XYZ';
require('http').get('https://www.googleapis.com/plus/v1/people/me/activities/public?access_token=' + accessToken, function(result){
//Use result here!
});
More information can be found within the Google+ API (Common Parameters) section