PostMan Pre-request script for fetching JWT using Laravel - javascript

I am trying to write a pre-request script for getting JWT for my postman tests using Laravel. I tried the js code that works perfect when I use .NET REST API, but now in Laravel it is not working. If I hit the login endpoint it works I got my JWT, and the response look like this:
{
"status_code": 200,
"access_token": "15|we59pMz1wA6TqwALTJg9IT8pNs3mc4Omwibm7Lkd",
"token_type": "Bearer"
}
Here is my pre-request JS script:
const requestBody =
{
"Email" : "username",
"Password" : "password"
}
pm.sendRequest
({
url: 'http://localhost:8000/api/login',
method: 'POST',
header:
{
'content-type': 'application/json'
},
body:
{
mode: 'raw',
raw: requestBody
}
}, function (err, res)
{
if(err)
{
console.log("Login failed:");
console.log(JSON.stringify(err));
return;
}
else
{
const response = res.json();
const token = 'Bearer ' + response.access_token;
pm.environment.set("TOKEN", token);
console.log("Login succeeded!");
}
});
The response in pre-request is this:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="refresh" content="0;url='http://localhost:8000'" />
<title>Redirecting to http://localhost:8000</title>
</head>
<body>
Redirecting to http://localhost:8000.
</body>
</html>

Your token doesn't seem like a JWT.
This is not base64 and does not contain the 3 parts: header, payload, signature.
Don't hesitate to look at my Postman pre request gist for JWT there are some explanations here too.
It contains one function to check the token validity:
/** Checks if the JWT is present and not expired
The token is expected to be found in `token` environment variable
*/
function isValidToken() {
const token = pm.environment.get("token");
if (!token) {
console.log("Token is missing");
return false;
}
// Payload is retrieved by
// JSON parsing the base64 decoded `atob()` 2nd part of the JWT `[1]`
// (1st is the header, 3rd is the signature)
const payload = JSON.parse(atob(token.split('.')[1]));
// Expiration timestamp (in seconds) is located in the `exp` key
const millisecBeforeExpiration = (payload.exp * 1000) - (new Date()).getTime();
if (millisecBeforeExpiration <= 0) {
console.log("Token is expired");
return false;
}
console.log("Token is valid",
`will expire in ${millisecBeforeExpiration / 1000} seconds`);
return true;
}
and one to get a new token
/** Gets a new JWT
This can be entirely custom authentication.
Here we rely on `user`/`pass` environment variables.
`host` also needs to be set, feel free to use another route instead of /give-me-a-jwt :)
*/
function login() {
const body = JSON.stringify({
"user": pm.collectionVariables.get("user"),
"pass": pm.collectionVariables.get("pass")
});
const request = {
url: pm.collectionVariables.get("host") + "/give-me-a-jwt",
method: "POST",
header: {
"Content-Type": "application/json",
"Accept": "application/json",
},
body,
};
pm.sendRequest(request, (err, res) => {
if (res.code !== 200) throw new Error(res.status);
console.log("Token refreshed");
pm.environment.set("token", res.json().token);
});
}
Now you can just get a new token if not valid:
if (!isValidToken()) login();
Of course don't forget to use your brand new token in your Postman's Bearer Token authentication type

Related

How to pass file(Image) via NextJS API Routes to external API?

I use NextJS (combined: SSR and SPA for authorized dashboard) with Django Rest FW on the backend. For auth I use JWT token, which is stored in cookies. For that reason, I need a middleware at /pages/api/* for each request to append from cookie access token.
Question:
How to implement a protected request to send file to /pages/api/upload and send it to DRF with an access token?
Sample of small API middleware
export default async (req, res) => {
const { id } = req.query
const cookies = cookie.parse(req.headers.cookie ?? "");
const access = cookies["access"] ?? false;
if (access === false) {
return res.status(401).json({
error: "User unauthorized to make this request"
});
}
if (req.method === "GET") {
try {
const apiRes = await fetch(`${LOCAL_API_URL}/items/${id}`, {
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Authorization": `Bearer ${access}`
}
});
const data = await apiRes.json();
if (apiRes.status === 200) {
return res.status(200).json(data);
} else {
return res.status(apiRes.status).json({
error: data.error
});
}
} catch(err) {
console.log(err);
return res.status(500).json({
error: "Something went wrong"
});
}
} else
res.setHeader("Allow", ["GET"]);
return res.status(405).json({
error: `Method ${res.method} is not allowed`
});
}
For sending image you should use FormData.
Firstly create an instance of FormData.
const formData = new FormData()
Then, you can add image into that.
formData.append('fieldName', someFileInput.current.files[0])
Also, if you want to add some more data with the image, you can append it to FormData too, the similar way.
formData.append('fieldName', someMoreData)
Then, you should set Content-Type to 'multipart/form-data', this is to server understand you pass the FormData.
And, finally, send the form data via Fetch.
I was glad to answer you, I hope it helps you!
the solution was raiser simple. Just passed everything I received and appended token to headers/
export default async (req, res) => {
// all extra validation
const apiRes = await fetch(`${LOCAL_API_URL}/upload/`, {
method: "POST",
headers: { ...req.headers, ...{ "Authorization": `Bearer ${access}` } },
body: req.body
});
// all extra validation
}

How to set headers while requesting a page in nodejs?

I saw many tutorials on jwt authentication but every video maker uses Postman to show what's happening and they pass on the header in the headers section while requesting a URL in Postman. I tried to do it with JavaScript but I was not able to do it.
I want to do jwt authentication but after token generation, I send it to client side to use it for further requests but I failed to do so after trying it a few times. I also tried to set req.headers in server side but it didn't do what I wanted to..
I want to set request headers for authentication of the form "Bearer {token}" for every request after token generation. How to do it with JS??
What I am most concerned about is that every tutorial does it with postman but they didn't show how they implemented it in their own app. I hope my question is clear.
You can easily add header on your http request like that
it has been solved here Node.JS: How to send headers with form data using request module
In vanilla nodejs:
const uri = "http://example.com";
const options = {
headers: {
"Authorization": "Bearer ...."
}
}
// require http/https lib
let req = require("http").request(uri, options, (res) => {
const chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.once("end", () => {
// concat body chunks
let body = Buffer.concat(chunks);
console.log(body.toString());
});
});
req.on("error", (err) => {
console.log(err);
});
req.end();
https://nodejs.org/dist/latest-v12.x/docs/api/http.html#http_http_request_options_callback
Something like that:
$.ajax({
url: url,
beforeSend: function(xhr) {
xhr.setRequestHeader("custom_header", "value");
},
success: function(data) {
}
});
First install jwt and express framework using npm then make a middleware file which will check if the tokek is set or not.
Middleware.js :
let jwt = require('jsonwebtoken');
const config = require('./config.js');
let checkToken = (req, res, next) => {
let token = req.headers['authorization']; // Express headers are auto converted to lowercase
if (token) {
if (token.startsWith('Bearer ')) { // Checks if it contains Bearer
// Remove Bearer from string
token = token.slice(7, token.length); //Separate Bearer and get token
}
jwt.verify(token, config.secret, (err, decoded) => { //Inser the token and verify it.
if (err) {
return res.json({
status: false,
message: 'Token is not valid'
});
} else {
req.decoded = decoded;
next();
}
});
} else {
return res.json({
status: false,
message: 'Access denied! No token provided.'
});
}
};
Next, create a config file which will contain the secrets.
Config js:
module.exports = {
secret: 'worldisfullofdevelopers'
};
Finally, create a token route which will create your token and after that the rest of the calls will be authenticated for that token.
Index.js :
const middleware = require('./middleware');
const jwt = require("jsonwebtoken");
const config = require('./config.js');
//Call token Route
app.use('/token', (req, res, next) => {
//Generate Token
let token = jwt.sign({ username: "test" },
config.secret,
{
expiresIn: '1h' // expires in 1 hours
}
);
//Send Token
res.json({
success: true,
message: 'Authentication successful!',
token: token
});
});
//Add Authentication to all routes
app.use(middleware.checkToken);
//===> All the routes after middleware will be checked for token
app.use('/getUser', (req, res, next) => {;
console.log('do something')
});
If I understand correctly, you want to set the HTTP header on the client, in order to pass an authentication token to the server. I would recommend that you use a library like **axios*.
Using axios, once you receive the toke, set the header for every outgoing communication with the following line of code:
axios.defaults.headers.common['Authorization'] = "Bearer " + token;
This will set the authentication http header to the form you need.

How to automate the OAuth 2.0 token generation using Artillery?

I want to automate the OAuth 2.0 token automatically via javascript. Is there any way I can do that and obtain the token to use it in the artillery scrtips.
For the OAuth token generation I have below details:
Auth URL
Client ID
Scope
It is done by client authentication credentials.
Below is the sample code I am using to generate the token:
var ClientOAuth2 = require('client-oauth2')
var Auth = new ClientOAuth2({
clientId: 'ClientID',
accessTokenUri: 'https://Auth_URL/v2.0/token',
authorizationUri: 'https://Auth_URL/v2.0/authorize',
redirectUri: 'https://Auth_URL/',
scope: 'api://Scope/access_as_user'
})
Auth.owner.getToken('Username', 'password')
.then(async (user) => {
await console.log(user) //=> { accessToken: '...', tokenType: 'bearer', ... }
}).catch((e) => { console.log('error show',e); })
.finally( () => console.log('end'));
You can declare your custom JS files which will be triggered every time before the request:
Your YAML file can be like here:
config:
target: "https://baseUrl.com"
phases:
- duration: 60
arrivalRate: 100
processor: "./customFile.js"
scenarios:
- flow:
- post:
url: "/pathInYourApi"
headers:
Content-Type: "application/json"
Accept: application/json
json: {}
beforeRequest: "beforeRequest"
and then your customFile.js script:
module.exports = {
beforeRequest: beforeRequest,
};
function beforeRequest(requestParams, context, ee, next) {
// Call your OAuth client, and after you obtain token you can assign it to requestParams Authorization header
// eg. requestParams.headers.Authorization = `Bearer + ${token}`
return next(); // MUST be called for the scenario to continue
}

Node.JS Invalid URI Error: GET Request using Query parameter

I am trying to do query to find a account using rest services of the target application name hexion.
When I am running it is giving Invalid uri error.
The url that I tested in postman is like below
https://ekaa-dev1.fa.us6.oraclecloud.com/crmRestApi/resources/11.13.18.05/accounts?q=OrganizationName = Hexion
and in postman I am getting response too.
But I feel somewhere in my code I am doing some syntax error but not able to find that
//nodejs v4.2.6
console.log("Hello, World!");
var Request = require("request");
var serviceUserName="msonawane#gmail.com";
var password="Welcome01";
var personalDataURL="https://ekaa-dev1.fa.us6.oraclecloud.com/crmRestApi/resources/11.13.18.05/accounts";
var option1 = {
uri: personalDataURL,
qs: {
q:{OrganizationName:"Hexion"}
},
headers: {
"Authorization" : auth,
"Content-Type": 'application/json',
"Accept":'application/json'
}
};
var auth = `Basic ` + new Buffer(serviceUserName+`:`+password).toString(`base64`);
Request.get(option1, { json: true },
(error, response, body) => {
console.log(response);
//console.log(response.url);
if (error) { return console.log(body,error); }
console.log(body.url);
console.log(body.explanation);
});
I expect it to return response after successful get
Please let me know error, I have changed the auth credentials so once you find anything to be corrected let me for the above code, I will try with right credentials and update you
request.get method expects first parameter as url, but you are passing options1 obj, it couldn't find url hence it is giving error "Invalid uri /".
You can append query parameter to url OR use querystring npm
var personalDataURL= "https://ekaa-dev1.fa.us6.oraclecloud.com/crmRestApi/resources/11.13.18.05/accounts?q=OrganizationName=Hexion"
request({
headers: {
"Authorization" : auth,
"Content-Type": 'application/json',
"Accept":'application/json'
},
uri: personalDataURL,
method: 'GET'
}, function (err, res, body) {
//it works!
});
For more details, refer request

Problem retrieving bearer access token using timer triggered Azure javascript function

I have an Azure Timer Triggered Function that needs to make various calls to the Graph API, which means I need an OAuth2 Bearer token issued by my tenancy's AAD.
So I've written the function below, which based on code I've previously written to make Ajax calls, which makes a call to AAD to get the Bearer token I need.
I've tested the URL, Client ID, Client Secret, and Grant Type settings using Postman and they returned a valid Bearer Token for me to use.
However the code makes the call, and nothing is returned, it just seems to hang.
When test-run in the Azure portal I get a
Status 503 Service Unavailable.
async function getToken() {
return new Promise((resolve, reject) => {
try {
let https = require("https");
let url =
"https://login.microsoftonline.com/<azure_tenancy>.onmicrosoft.com/oauth2/token";
let options = {
method: "POST",
headers: {
"Content-Type": "application/json; charset=utf-8",
"Cache-Control": "no-cache"
}
};
let body = {
grant_type: "client_credentials",
client_id: "<client_id>",
client_secret: "client_secret>",
resource: "https://graph.microsoft.com"
};
var req = https
.request(url, options, res => {
let data = "";
res.on("data", chunk => {
data += chunk;
});
res.on("end", () => {
resolve(JSON.parse(data));
});
})
.on("error", err => {
throw new Exception(e.message);
});
req.write(JSON.stringify(body));
req.end();
} catch (e) {
context.log("error caught");
reject(e);
}
});
}
Postman returns:
{
"token_type": "Bearer",
"expires_in": "3600",
"ext_expires_in": "3600",
"expires_on": "1558542984",
"not_before": "1558539084",
"resource": "https://graph.microsoft.com",
"access_token": "eyJ...e8mw"
}
So I know the URL, ID, and Secret I'm passing are correct. It must be something else in the code but I'm baffled as to what. Any clues?

Categories

Resources