Token in postman not able to fetch the value - javascript

I am setting the access token in my environment variable which will fetch the value from a Pre-request script that I have written and placed in my collection but when I try to run the request it gives me error saying "Message": "Response status code does not indicate success: 401 (Unauthorized)."
but to validate if my token is correct or not I have pasted it directly to the bearer token in the request (took directly from the site) then it works fine. Not sure why in the environment variable it is fetching some different kind of token due to which I am getting this unauthorised error. This token is not matching with the real token when I compared from my site.
My request:
GET:{{Url}}/api/Ids/
const echoPostRequest = {
url: pm.environment.get('tokenUrl'),
method: 'POST',
header: 'Content-Type:application/x-www-form-urlencoded',
body: {
mode: 'urlencoded',
urlencoded: [
{ key: "id", value: pm.environment.get('Id') }
]
}
};
var getToken = true;
if (!pm.environment.get('accessTokenExpiry') ||
!pm.environment.get('accessToken')) {
console.log('Token or expiry date is missing')
} else if (pm.environment.get('accessTokenExpiry') <= (new Date()).getTime()) {
console.log('Token is expired')
} else {
getToken = false;
console.log('Token and expiry date are all good');
}
if (getToken === true) {
pm.sendRequest(echoPostRequest, function (err, res) {
console.log(err ? err : res.json());
if (err === null) {
console.log('Saving the token and expiry date')
var responseJson = res.json();
pm.environment.set('accessToken', responseJson.access_token)
var expiryDate = new Date();
expiryDate.setSeconds(expiryDate.getSeconds() + responseJson.expires_in);
pm.environment.set('accessTokenExpiry', expiryDate.getTime());
}
});
}
Please suggest.
Thanks in advance.

can you provide what you are using to access token value or you can paste collection so that we can get more data one request

Related

How to fetch JWT token in postman pre-request script?

I am new to using postman to test api. I am trying to fetch a JWT token which I can save as an environment variable in postman. I was referring to this excellent post on how to do it: jwt-postman
I have the below python code which I used before in order to fetch the jwt token.
import requests
from requests.auth import HTTPBasicAuth
import json
session=requests.Session()
client_id ="abcdef"
secret="ghijklmnop"
token_auth="https://TEST/token"
hed = {'Content-Type': 'application/x-www-form-urlencoded'}
response = session.post(token_auth,headers =hed ,data = 'grant_type=client_credentials',auth = HTTPBasicAuth(client_id,secret),verify = True)
token = json.loads(response.content)['access_token']
print(token)
How do I write the same functionality in pm.sendRequest ?
I've not been able to run this but you're going to need to do something like this:
const options = {
url: 'https://TEST/token',
method: 'POST',
header: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: {
mode: 'urlencoded',
urlencoded: [
{ key: "client_id", value: "abcdef" },
{ key: "client_secret", value: "ghijklmnop" },
{ key: "grant_type", value: "client_credentials" },
]
}
};
var getToken = true;
if (!pm.environment.get('accessTokenExpiry') ||
!pm.environment.get('currentAccessToken')) {
console.log('Token or expiry date are missing')
} else if (pm.environment.get('accessTokenExpiry') <= (new Date()).getTime()) {
console.log('Token is expired')
} else {
getToken = false;
console.log('Token and expiry date are all good');
}
if (getToken === true) {
pm.sendRequest(options, function (err, res) {
console.log(err ? err : res.json());
if (err === null) {
console.log('Saving the token and expiry date')
var responseJson = res.json();
pm.environment.set('currentAccessToken', responseJson.access_token)
var expiryDate = new Date();
expiryDate.setSeconds(expiryDate.getSeconds() + responseJson.expires_in);
pm.environment.set('accessTokenExpiry', expiryDate.getTime());
}
});
}

MailChimp Error Status: 401 Title: "API Key Invalid"

I am following a MailChimp API tutorial
When I test the API, I get a 401 response saying my API key is invalid.
Error -
Status: 401
"Your API key may be invalid, or you've attempted to access the wrong datacenter."
I have yet to register a domain yet, this is being testing using a local server. Could this be error be caused by MailChimp's refusing the request for another reason, perhaps CORS?
app.post('/signup', (req, res) => {
// Get form data
const { email } = req.body;
// Make sure field is filled
if(!email) {
res.redirect('/html/fail.html');
return;
}
// Construct req data
const data = {
members: [
{
email_address: email,
status: 'subscribed'
}
]
}
// Convert to JSON
const postData = JSON.stringify(data);
const options = {
url: 'https://us19.api.mailchimp.com/3.0/lists/listID',
method: 'POST',
headers: {
Authorization: 'auth xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-us19'
},
body: postData
};
request(options, (err, response, body) => {
if(err) {
console.log(err);
res.redirect('/html/fail.html');
} else {
if(response.statusCode === 200) {
res.redirect('/html/success.html');
} else {
console.log(response.body);
res.redirect('/html/fail.html');
}
}
});
})
I tried running the same code in request in PostMan and I got back a 200 response.
I was initially importing the API key from a config file, that I had not destructured...

Fetch googlesheet data using access token?

I want to fetch googlesheet data. Through my code I am able to get the access token but now I don't know how can I fetch all the records in a googlesheet using that particular access token in javascript.
I have given the scope in manifest as spreadsheet.readonly.
I have my token in a particular variable and also googlesheeetId in another variable now what headers and what url do I need to paas so that I can get the googlesheet data.
Please help with some reference or links or sample code so that I can get a glimpse of what process do I need to follow to do this.
Here is the code
var gSheetId;
chrome.identity.getAuthToken({ 'interactive': true }, function (token) {
if (chrome.runtime.lastError) {
console.log(chrome.runtime.lastError);
return;
}
console.log(token);
//getting googlesheetId from user
gSheetId = prompt("Please provide your googlesheet Id");
if (!gSheetId) {
alert("Operation Cannot be Performed! Please refresh");
}
else {
//read googlesheetdata
var headers = {
'Authorization':'Bearer '+token
}
//here I need to read the googlesheet data using the token
chrome.debugger.onEvent.addListener(onEvent);
}
});
Thanks in advance!
Solution
Brought to you by #StayAtOrbit , owner of the oiginal question. (this is a community wiki answer)
Useful resources for this issue:
Google sheets API documentation for JavaScript
Sending access token to an API
Making authentificated requests with a token
var gSheetId;
chrome.identity.getAuthToken({ 'interactive': true }, function (token) {
if (chrome.runtime.lastError) {
console.log(chrome.runtime.lastError);
return;
}
console.log(token);
//getting googlesheetId from user
gSheetId = prompt("Please provide your googlesheet Id");
if (!gSheetId) {
alert("Operation Cannot be Performed! Please refresh");
}
else { //read googlesheetdata
var obj = {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Host': 'sheets.googleapis.com',
'Authorization': 'Bearer '+token
}
}
fetch('https://sheets.googleapis.com/v4/spreadsheets/<sheetID>/values/<range>', obj)
.then(function (res) {
return console.log(res.json());
}).then(function (resJson) {
return console.log(resJson);
})
//here I need to read the googlesheet data using the token
chrome.debugger.onEvent.addListener(onEvent);
}
});

How should I pass variables from my external routes to a javascript controller in Node.js asynchronously?

My external routes is setup so that a POST form sends data to my server and my server file validates the input. It then takes this input and passes it to another file which will then perform authentication. I have a few questions regarding this, which are:
1) Do I need to pass the data asynchronously?
2) Is the way I am currently passing synchronous? Should it be changed
3) If I want to pass my variables into this file and it uses an async waterfall, (I believe I can't pass variables into the first function) should I create a main function which has two sub functions (one for storing the variables and one for executing the async waterfall)?
I am new to Node.js so have only just started learning the concept of asynchronous functionality. Any tips, help or questions, please let me know. If i have left something out please ask
My Server function is as such:
//Route for POST requests to Login
//First Sanitise input!
app.route('/login').post([
//ACCOUNTTYPE CHECKS -------------------------------------------------------------------------------
check('accountType').exists()
.trim()
.isAlpha()
.isLength({
min: 8,
max: 10
})
.matches(/(Production|Internal)/).withMessage('Must be either \'Production\' or \'Internal\'\!')
.escape(),
//CUSTOMERID CHECKS --------------------------------------------------------------------------------
check('customerID').exists()
.trim()
.isNumeric()
.isInt()
.isLength({
max: 40
})
.escape(),
//CLIENTID CHECKS ---------------------
check('clientID').exists()
.trim()
.isAlphanumeric()
.isLength({
max: 40
})
.escape(),
//CLIENTSECRET CHECKS ---------------------
check('clientSecret').exists()
.trim()
.isAlphanumeric()
.isLength({
min: 0,
max: 45
})
.escape(),
//USERNAME CHECKS ---------------------
check('username').exists()
.trim()
.isEmail()
.isLength({
min: 0,
max: 100
})
.escape(),
//PASSWORD CHECKS ---------------------
check('password').exists()
.trim()
.isLength({
min: 0,
max: 100
})
.escape()
], urlencodedParser, (req, res) => {
let now = new Date().toString(),
log = `${now}: ${req.method} ${req.url}`,
sess = req.session;
console.log(req.body);
fs.appendFile('server-requests.log', log + '\n', (err) => {
if (err) {
console.log('Unable to append to server-requests.log!');
}
});
// Finds the validation errors in this request and wraps them in an object with handy functions
const errors = validationResult(req);
if (!errors.isEmpty()) {
//return a bad status and array of errors
//if the validation fails
// return res.status(422).json({
// errors: errors.array()
// });
//OR:
return res.render('login.hbs', {
currentYear: new Date().getFullYear(),
//This does not work realtime - FIX TODO
currentTime: moment().format('MMMM Do YYYY - h:mm:ss a'),
data: {},
errors: errors.mapped()
});
// If there aren't any errors, proceed to save variable data and use 2.0
} else {
//Handle with event emiitters and make asynchronous - TODO
const data = matchedData(req);
console.log('Data stored in session:')
console.log('Sanitised:', data);
//Store Form Data in session variables
sess.accountType = data.accountType,
sess.customerID = data.customerID,
sess.clientID = data.clientID,
sess.clientSecret = data.clientSecret,
sess.username = data.username,
sess.password = data.password;
console.log('Sanitised POST Form! Now initialising request.');
req.flash('success', 'Successful POST request, proceeding to authorisation...)');
//Make asynchronous?
//use each function and get variables
auth.saveVariables(sess.accountType, sess.customerID, sess.clientID, sess.clientSecret, sess.username, sess.password);
auth.asyncWaterfall(callback)
res.redirect('/index');
//Or alternatively should it redirect with a query string?
// const url = require('url');
// app.get('/index', function (req, res) {
// res.redirect(url.format({
// pathname: "/",
// query: {
// "acccountType": 1,
// "customerID": 2,
// "clientID": 3,
// "clientSecret": 4,
// "username": 5,
// "password": 6
// }
// }));
// });
}
})
Here is the start of my auth controller code:
const saveVariables = (accountType, customerID, clientID, clientSecret, username, password, callback) => {
//Test parameters
if (accountType.type() !== String || customerID.type() !== String || clientID.type() !== String || clientSecret.type() !== String || username.type() !== String || password.type() !== String) {
let fields = [accountType, customerID, clientID, clientSecret, username, password];
test(fields);
}
accountType,
customerID,
clientID,
clientSecret,
username,
password;
}
const test = (array) => {
array.forEach((field) => {
let errorString;
if (field.type() !== String) {
errorString += `The field ${field} is not a String. Type: ${field}.`
}
return errorString;
})
}
//This const creates the auth URL and auth code grant URL. It also assigns the host URL.
const createAuthURL = (callback) => {
//If the paramter test passes then proceed
if (accountType === "Production") {
try {
let authURL = `https://${prodURL}${url1}`,
authCodeURL = `https://${prodURL}${url2}`,
host = prodURL;
} catch (e) {
console.log(`Error occurred when assigning url variables (Production). Error: ${e}`);
console.error('Error occurred when assigning url variables (Production). Error:', e);
}
} else if (accountType === "Internal") {
try {
let authURL = `https://${internURL}${url1}`,
authCodeURL = `https://${internURL}${url2}`,
host = internURL;
} catch (e) {
console.log(`Error occurred when assigning url variables (Internal). Error: ${e}`);
console.error('Error occurred when assigning url variables (Internal). Error:', e);
}
} else {
console.log(`Bad String Input into auth URL! Entry: ${accountType}`);
console.error('Bad String Input into auth URL: ', accountType);
}
}
const asyncWaterfall = (req, res) => {
//Asynchronous Waterfall Call of 'Getting Access Tokens' (Stages 1-3)
async.waterfall([
getCookieData,
getAuthCode,
getAccessToken
], (err, result) => {
if (err) {
alert('Something is wrong!');
}
return alert('Done!');
});
//STAGE 1 - USE CUSTOMER DETAILS TO RETRIEVE COOKIE AND CSRF SESSION DATA
getCookieData = async (callback) => {
//For testing purposes - Remove after development
console.log(`The type of account used is: ${accountType}`);
console.log(`The customerID used is: ${customerID}`);
console.log(`The clientID used is: ${clientID}`);
console.log(`The client secret used is: ${clientSecret}`);
console.log(`The username used is: ${username}`);
console.log(`The password used is: ${password}`);
console.log(`Making a URL request to: ${authURL}`);
//If the paramter test passes then proceed
var options = {
//Type of HTTP request
method: 'POST',
//URI String
uri: authURL,
//HTTP Query Strings
qs: {
'client_id': clientID
},
//HTTP Headers
headers: {
'cache-control': 'no-cache',
'Accept': 'application/json',
'Host': host,
'Content-Type': 'application/json'
},
//HTTP Body
body: {
'username': username,
'password': password
},
json: true // Automatically stringifies the body to JSON
//resolveWithFullResponse: true // Get the full response instead of just the body
//simple: false // Get a rejection only if the request failed for technical reasons
};
console.log(`Beginning HTTP POST Request to ${authURL}...`);
//await literally makes JavaScript wait until the promise settles, and then go on with the result.
await rp(options)
.then((parsedBody) => {
//POST Succeeded...
Console.log('Successful HTTP POST!');
try {
let csrf = response.body('csrftoken'),
ses = response.body('session'),
sesk = `session=${ses}`;
} catch (e) {
console.log(`STAGE 1 - Error occurred when assigning url variables. Error: ${e}`);
console.error('STAGE 1 - Error occurred when assigning url variables. Error:', e);
}
console.log(`Successful grab of the cookie: ${ses} and csrf token: ${csrf}. Getting authorisation code now!`);
//Asynchronous callback for the next function - return = defensive architecture
return callback(null, authCodeURL, customerID, clientID, csrf, sesk);
})
.catch((err) => {
if (res.statusCode == 400) {
console.log(`Error Message: ${res.body.message}. Status: ${res.body.status}`);
console.error('Error Message:', res.body.message, 'Status:', res.body.status);
} else if (res.statusCode == 401) {
console.log(`Error Message: ${res.body.message}. Status: ${res.body.status}`);
console.error('Error Message:', res.body.message, 'Status:', res.body.status);
} else {
console.log(`Failed to retrieve the cookie data! Error: ${error}`);
console.error('Failed to retrieve the cookie data! Error:', error);
}
});
},
//STAGE 2 - USE COOKIES AND CSRF TOKEN TO GET AUTH CODE
//Is the word async needed? it is not asyncchronous but sequential
getAuthCode = async (authCodeURL, customerID, clientID, csrf, sesk, callback) => {
//Make sure all the data is in string format - Run Time Tests
if (authCodeURL !== String || cutomerID !== String || clientID !== String || csrf !== String || sesk !== String) {
let fields = [authCodeURL, cutomerID, clientID, csrf, sesk];
test(fields);
}
//If successful, proceed:
var options = {
method: 'POST',
uri: authCodeURL,
qs: {
'client_id': clientID,
'response_type': 'code',
'scope': 'all'
},
headers: {
'X-CSRF-TOKEN': csrf,
'Accept': 'application/json',
'Cookie': sesk,
'Content-Type': 'application/json'
},
body: {
'customer_id': customerID
},
json: true // Automatically stringifies the body to JSON
};
console.log(`Beginning HTTP POST Request to ${authCodeURL}...`);
//await literally makes JavaScript wait until the promise settles, and then go on with the result.
await rp(options)
.then((parsedBody) => {
//POST Succeeded...
Console.log('Successful HTTP POST!');
try {
let authCode = response.body.JSON('auth_code'),
swapurl = `https://${host}${url3}`;
} catch (e) {
console.log(`STAGE 2 - Error occurred when assigning url variables. Error: ${e}`);
console.error('STAGE 2 - Error occurred when assigning url variables. Error:', e);
}
console.log(`The authorisation Code is ${authcode}. Getting Access Token now!`);
//Asynchronous callback for the next function - return = defensive architecture
return callback(null, swapURL, clientID, clientSecret, authCode);
})
.catch((err) => {
if (res.statusCode == 400) {
console.log(`Error Message: ${res.body.message}. Extra: ${res.body.extra}`);
console.error('Error Message:', res.body.message, 'Extra:', res.body.extra);
} else {
console.log(`Failed to retrieve the authorisation code! Error: ${error}`);
console.error('Failed to retrieve the authorisation code! Error: ', error);
}
});
},
//STAGE 3 - USE AUTH CODE TO GET ACCESS TOKEN
//ASYNC NEEDED?
getAccessToken = async (swapURL, clientID, clientSecret, authCode, callback) => {
//Make sure all the data is in string format - Run Time Tests
if (swapURL !== String || clientSecret !== String || clientID !== String || authCode !== String) {
let fields = [swapURL, clientSecret, clientID, authCode];
test(fields);
}
//If successful, proceed:
var options = {
method: 'POST',
uri: swapURL,
qs: {
'client_id': clientID,
'grant_type': 'authorization_code',
'client_secret': clientSecret,
'code': authCode
},
json: true // Automatically stringifies the body to JSON
};
console.log(`Beginning HTTP POST Request to ${swapURL}...`);
//await literally makes JavaScript wait until the promise settles, and then go on with the result.
await rp(options)
.then((parsedBody) => {
//POST Succeeded...
Console.log('Successful HTTP POST!');
try {
let accessToken = response.body('access_token'),
refreshToken = response.body('refresh_token');
} catch (e) {
console.log(`STAGE 3 - Error occurred when assigning url variables. Error: ${e}`);
console.error('STAGE 3 - Error occurred when assigning url variables. Error:', e);
}
console.log(`The access Token is ${accessToken} and the refreshToken which is ${refreshToken}! These are only valid for 2 hours!`);
//Asynchronous callback for the waterfall - return = defensive architecture
return callback(null, 'done');
})
.catch((err) => {
console.log(`Failed to retrieve the access/refresh Token! Error: ${error}`);
console.error('Failed to retrieve the access/refresh Token! Error:', error);
});
}
}

Get Current Users: Google Real Time API with NodeJS & gtoken: "Invalid Credentials"

I would like to use a NodeJS Server to obtain the current users on my Website from Google Analytic using the Real Time Reporting API:
So far I try to do this via an HTTP request with request and gtoken. The getToken-Part works. I get a token. But the HTTP-Request doesnt work. I get an "Invalid Credentials" Error with Code 401.
Does anybody have an idea what to do? Maybe this is the completely wrong approach to get these data.
var received_token;
var url = "https://www.googleapis.com/analytics/v3/data/realtime";
var paramsObject = { ids:"ga:123456789"};
const gtoken = new GoogleToken({
keyFile: 'pathToServiceAccountJSONKeyFile:',
scope: ['https://www.googleapis.com/auth/analytics.readonly']
});
gtoken.getToken(function(err, token) {
if (err) {
console.log(err);
return;
}
received_token = token;
console.log(token);
request({
url: url,
qs: paramsObject,
headers: {
'Authorization': received_token
}
}, function(err, response, body) {
if(err) { console.log(err); return; }
// console.log(response);
console.log(body);
});
I found the error :-)
In the Authorization Header "Bearer" was missing, now it works like charm and I receive data from the Google Real Time API.
headers: {
'Authorization': "Bearer " +received_token
}

Categories