Aurelia fetch-client throws 401 for post requests - aurelia-fetch-client

I'm facing an issue while trying to make httpPost request.
It always returns 401 Unauthorized error.
We are using token based authentication from our server(Apache Tomcat7) with SpringSecurity plugin for generating authToken.
Below is how I configured HttpClient.
In constructor, I made httpClient configuration.
#inject(HttpClient)
export default class UtilService {
constructor(http) {
// Configure the HttpClient globally ( in entire app)
http.configure(_http => {
_http
.useStandardConfiguration()
.withBaseUrl(config.baseUrl)
.withDefaults({
credentials: "same-origin",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"X-Requested-With": "Fetch",
"Accept": "*/*",
"Authorization": "Bearer "+localStorage[config.tokenName]
}
})
.withInterceptor({
responseError(error) {
if (error.status && error.status === 401) {
console.log("error recorded:"+error)
}
throw error;
}
});
});
this.http = http;
}
}
And calling function:
profileInfo(url, paramsObj) {
// url = http://localhost:8082/xyz/api/v1/profileInfo
// paramsObj = {access_token : localStorage[config.tokenName]};
return this.http.fetch(url, {
method: "POST",
body: $.param(paramsObj)
}).catch(err=>{
console.log("failure:"+err);
throw err
});
}
I always get 401 (Unauthorized).
Any help would be appreciated.

Related

Issue sending a JSON object to Stripe

I am trying to send a JSON Object to Stripe, but I am always receiving an error from the response.
API resolved without sending a response for /api/ctrlpnl/products_submit, this may result in stalled requests.
{
error: {
code: 'parameter_unknown',
doc_url: 'https://stripe.com/docs/error-codes/parameter-unknown',
message: 'Received unknown parameter: {"name":"dasdas"}',
param: '{"name":"dasdas"}',
type: 'invalid_request_error'
}
}
My code is below:
import Stripe from 'stripe';
import { NextApiRequest, NextApiResponse } from 'next';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
apiVersion: '2020-08-27'
});
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method === 'POST') {
try {
const name = { name: req.body.name };
fetch(`${process.env.BASE_URL}/v1/products`, {
method: 'POST',
body: JSON.stringify(name),
headers: {
'Accept': 'application/json',
"content-type": 'application/x-www-form-urlencoded',
Authorization: `Bearer ${process.env.STRIPE_SECRET_KEY}`,
}
}).then((response) => {
return response.json();
}).then(data => {
console.log(data);
res.status(200).json(data)
})
} catch (err) {
res.status(err.statusCode || 500).json(err.message);
}
} else {
res.setHeader('Allow', 'POST');
res.status(405).end('Method Not Allowed');
}
}
The content-type of the fetch is correctly set to application/x-www-form-urlencoded, but the body contains a json. So Stripe is unable to parse the body parameters.
To fix that, you need to replace JSON.stringify by new URLSearchParams:
const name = { name: req.body.name };
fetch(`${process.env.BASE_URL}/v1/products`, {
method: 'POST',
body: new URLSearchParams(name), // ← this will return "name=xxxx"
headers: {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': `Bearer ${process.env.STRIPE_SECRET_KEY}`,
}
});
Note that I recommend using the Stripe library which is much simpler to use: stripe.products.create(name);, especially since you already included it in your code.

express redirect got response 304 and do nothing

frontend is react and request to server use Fetch .
code like this .
fetch(`/ONETOWN/LARK/PACKAGE/STOCKOUT/LOAD_LIST_BY_TELL`,{
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
},
credentials: 'include',
body: JSON.stringify(info)
})
the backend(server) code like this,cookie expired,so i hope redirect to unauthorized page .
static authentication(req,res) {
if(this.verifyCookie(req,res)) {
return true;
}
//res.status(401).end();
res.redirect('/#/page/unauthorized');
return false;
}
my Web don't redirect to the path i want,still stay the original page
if Redirect change to Location method
res.location('/#/page/unauthorized').end()
got response 200
got response 200
The thing is that you are using a fetch call to make an HTTP call, so your browser is not making a request, so it knows nothing that it needs to open a different page.
The solution is to check the response of your fetch call and make a redirect to the different page if needed.
thanks #Ayzrian, i have change my code logic to fix this problem . you are right , i shoud do redirecting in frontend , check server response's status(401) , code like this .
enter code here
fetch(`url`,{
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
},
credentials: 'include',
body: JSON.stringify(info)
})
.then(res => Authentication(res))
.then(res => res.json())
.then(json => {
}).catch((e) => {
if (e.status === 401) {
console.log(e);
window.location="#/page/unauthorized";
}
});
};
.......................
export const Authentication = (res) => {
if (res.ok) {
return res;
} else {
return Promise.reject({
status: res.status,
statusText: res.statusText
});
}
}
................
static authentication(req,res) {
if(this.verifyCookie(req,res)) {
return true;
}
res.status(401).end();
//res.redirect('/#/page/unauthorized'); not works
return false;
}

Axios Proxy Configuration causing Bad Request

I am trying to send a request to the particle cloud from a NodeJS application.
I am using Axios to make the PUT request. The application sends the request through a proxy server which is configured as well.
// axios proxy - not working
axios.default.put("https://api.particle.io/v1/devices/<deviceId>/ping", {}, {
proxy: {host: <proxy_ip>, protocol:'http', port:<port_no>},
headers: {
authorization: "Bearer <access_token>"
}
}).then((response) => {
console.log("Success", response.data);
}).catch((error) => {
console.log("Failed", error);
});
Error Message: Request failed with status code 400
When I send this request I get a 400 Bad Request response from the particle cloud.
But when I send the same request using the request module of NodeJS, the request is successful.
var options = {
method: 'PUT',
url: 'https://api.particle.io/v1/devices/<device_id>/ping',
proxy: {hostname: <proxy_ip>, protocol:'http', port:<port_no>},
headers:
{
authorization: 'Bearer <access_token>'
},
form: false
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(response);
});
Response: body: '{"online":false,"ok":true}'
The request also works when the application was deployed on the open network and axios was used without the proxy configuration.
// axios without proxy - working
axios.default.put("https://api.particle.io/v1/devices/<deviceId>/ping", {}, {
headers: {
authorization: "Bearer <access_token>"
}
}).then((response) => {
console.log("Success", response.data);
}).catch((error) => {
console.log("Failed", error);
});
Questions:
Why is the request from Axios failing with proxy configuration?
Is this an inherent issue with Axios?
Regards.
Axios itself has a bug which isnt fixed yet.
To overcome this issue, https-proxy-agent can be used instead of axios proxy.
const HttpsProxyAgent = require('https-proxy-agent')
axios.default.put("https://api.particle.io/v1/devices/<deviceId>/ping", {}, {
headers: {
authorization: "Bearer <access_token>"
},
proxy: false,
httpsAgent: new HttpsProxyAgent('http://proxy_domain:port')
}).then((response) => {
console.log("Success", response.data);
}).catch((error) => {
console.log("Failed", error);
});

Proxy API request through Express return pending Promise instead of response

I am currently trying to work with the Atlassian Jira rest API. In order to not get a CORS error I go through the recommended route of not sending the request from the browser but proxy it through my express server.
Now as I am doing this, all I receive back in the app is a pending promise. I assume that I have not correctly resolved it at one point but I cant figure out where.
API Handler sending the request to the proxy:
const baseURL = `${apiConfig}/jiraproxy`;
export const testConnection = integration => {
return fetch(`${baseURL}/get`, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify(integration)
})
.then(handleResponse)
.catch(handleError);
};
Jira Proxy Endpoint on the Express Server
const baseURL = `rest/api/3/dashboard`;
router.post("/get", (req, res) => {
fetch(req.body.link + baseURL, {
method: "GET",
headers: { Accept: "application/json" },
auth: {
username: req.body.credentials.username,
password: req.body.credentials.token
}
})
.then(handleResponse)
.catch(handleError);
});
handleResponse & handle Error Methods:
async function handleResponse(response) {
if (response.ok) {
return response.json();
}
if (response.status === 400) {
const error = await response.text();
throw new Error(error);
}
throw new Error("Network response was not ok.");
}
function handleError(error) {
// eslint-disable-next-line no-console
console.error(`API call failed. ${error}`);
throw error;
}
Goal:
Send the request of sending a request to the proxy and return the resonse of the proxy as the return of the initial "testConction" method.
Error:
No errors thrown, but the response received in the Browser is a pending promise.
Change to the Jira Proxy router fixed it. Thanks to #jfriend00.
router.post("/get", (req, res) => {
return fetch(req.body.link + baseURL, {
method: "GET",
headers: { Accept: "application/json" },
auth: {
username: req.body.credentials.username,
password: req.body.credentials.token
}
})
// This is the part that changed
.then(response => handleResponse(response))
.then(jiraResponse => res.status(200).json(jiraResponse))
.catch(handleError);
});

incorrect behaviour of node-fetch while trying to get token from an api

I want to connect to an external api using some node-fetch code. My code first sends the login details & should receive a token from the api. Then this token is used for all the later communications.
Here is the code :
import fetch from 'node-fetch';
function getTokenForAuth(info) {
try {
var auth_token = '';
fetch(api_url + '/api/api-token/', {
method: 'POST',
body: JSON.stringify(info),
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
})
.then(function(res) {
return res.json();
})
.then(function(json) {
auth_token = json;
})
return auth_token.token;
}
catch (e) {
console.log('[-] Error: Token Not Received');
console.log('[!] Exception: ' + e);
}
}
function getJSONFromRelativeURL(relativeURL, info) {
return fetch(`${api_url}${relativeURL}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Token ' + getTokenForAuth(info)
}
})
.then(function(res) {
console.log(res);
return res.json();
})
.then(function(json) {
console.log(json);
})
}
In the getJSONFromRelativeURL() function's request headers, if I hardcode the token, I get correct results. But if I run the code as it is now, I get an error saying : { detail: 'Invalid token.' }.
I think this is because of async nature of the promise in the fetch function, because of which it sometimes isnt able to send the token in time before the getJSONFromRelativeURL() gets called. I am not sure about this hypothesis & don't know how to correct this.
Your problem is here:
.then(function(json) {
auth_token = json;
})
return auth_token.token;
Your return statement is outside the Promise chain. This means that, at the point you hit return, the fetch request hasn't had a chance to even run yet. You've essentially just told the fetch Promise chain what to do when it does return.
So essentially
I think this is because of async nature of the promise in the fetch function, because of which it sometimes isnt able to send the token in time before the getJSONFromRelativeURL() gets called.
is 100% correct.
What you'll need to do is restructure things a little bit:
function getTokenForAuth(info) {
return fetch(api_url + "/api/api-token/", {
method: "POST",
body: JSON.stringify(info),
headers: {
"Content-Type": "application/json",
Accept: "application/json"
}
}).then(function(res) {
return res.json();
});
}
function getJSONFromRelativeURL(relativeURL, info) {
return getTokenForAuth(info)
.then(function(token) {
return fetch(`${api_url}${relativeURL}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: `Token ${token}`
}
});
})
.then(function(res) {
console.log(res);
return res.json();
})
.then(function(json) {
console.log(json);
});
}
Have not tested it but it looks something like the following. For error handling use .catch(()=>{}) at the end of each chain.
function getTokenForAuth(info) {
var auth_token = '';
return fetch(api_url + '/api/api-token/', {
method: 'POST',
body: JSON.stringify(info),
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
})
.then(function(res) {
return res.json();
})
}
function getJSONFromRelativeURL(relativeURL, info, token) {
return fetch(`${api_url}${relativeURL}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Token ' + token
}
})
.then(function(res) {
console.log(res);
return res.json();
})
.then(function(json) {
console.log(json);
})
}
getTokenForAuth(info)
.then((token)=>{
return getJSONFromRelativeURL(relativeURL, info, token)
})

Resources