Axios 419 (unknown status) Laravel API csrf token gets changed - javascript

I'm getting the error when I'm requesting my Laravel backend with Axios and getting the data back and requesting another API for some data and that goes well but after the API returns the data and I request my laravel backend to store the data. It returns a response with
app.js:360 POST http://technotrace.tech/session-adding-api 419 (unknown status)
I've tried checking on my PHP backend and this only stops if I'm disabling the VerifyCSRFToken middleware group.
But I need to check the CSRF token anyway for security reasons.
I'm able to understand why the csrf token gets changed on sending request.
If I'm doing just sending the request to my laravel backend then everything goes right but when I'm requesting another api then the problem arrives on sending the request to my backend.
function addSession(url, formdata) {
//Add Session
axios.post(url, formdata)
.then(res => {
console.log(res)
var data = res.data;
if ((data.session_info != null && data.session_info != {})) {
console.log(data.session_info);
}
})
.catch(err => {
console.error(err);
})
}
function getApiDetails() {
//Start getting api details
axios.get('https://ipapi.co/json/').then(res => {
console.log(res)
var csrf = jr('meta[name="csrf-token"]').get(0).content;
var ses_id = jr('meta[name="verify-token"]').get(0).content;
var cur_url = jr('link[rel="canonical"]').get(0).href;
// console.log(csrf, ses_id, cur_url);
var url = '/session-adding-api';
var formdata = new FormData();
formdata.append('_token', csrf);
formdata.append('session_token', ses_id);
formdata.append('session_repeat', 0);
formdata.append('current_url', cur_url);
Object.entries(res.data).forEach(entry => {
// console.log(entry[0], entry[1]);
formdata.append(entry[0], entry[1]);
});
addSession(url, formdata);
})
.catch(err => {
console.error(err);
})
//End getting api details
}
function matchSession() {
//Match Session Start
var csrf = jr('meta[name="csrf-token"]').get(0).content;
var ses_id = jr('input[name="verify-token"]').get(0).content;
var url = '/session-matching-api';
var formdata = new FormData();
formdata.append('_token', csrf);
formdata.append('session_token', ses_id);
axios.post(url, formdata)
.then(res => {
console.log(res)
var data = res.data;
if ((data.match != true)) {
getApiDetails()
}
})
.catch(err => {
console.error(err);
})
//Match Session
}
matchSession();

Related

an empty object arrives in my backend server when i send from my frontend

An empty object arrives in my backend server when I send from my frontend.
My backend server should work fine as I tested it with postman. When I send the following JSON via postman I get a 200 response.
{"email":"tom#gmail.com","password":"123456"}
I have a problem when I send the object via my frontend-code to my backend. The backend server crashes because it recieves an empty object. Why is that?
When i console.log enteredUsername, it's not empty
console.log(enteredUsername, enteredPassword);
let url = "http://localhost:4000/"
fetch(url, {
method: 'POST',
body: JSON.stringify({
email: enteredUsername,
password: enteredPassword
}),
headers: {
'Content-Type': 'application/json',
},
mode: 'no-cors'
}).then(res => {
if (res.ok) {
return res.json();
} else {
return res.json().then((data) => {
let errorMessage = 'Authentication failed!';
// if (data && data.error && data.error.message) {
// errorMessage = data.error.message;
// }
throw new Error(errorMessage);
});
}
})
.then((data) => {
console.log(data);
})
.catch((err) => {
alert(err.message);
});
}
This is the code from my backend server. When i console.log user, it's empty
router.post('/', async (req,res)=>{
console.log(req.body);
const result = await data.addUser(req.body);
res.send(result);
});
this is the method addUser:
async function addUser(user){
const connectionDB = await connection.getConnection();
console.log(user);
user.password = bcrypt.hashSync(user.password,8);
const result = await connectionDB.db('my-website')
.collection('users')
.insertOne(user);
return result;
}
I get this error in my console of my browser:
POST http://localhost:4000/ net::ERR_CONNECTION_RESET
Thank you very much for helping me.

How to get the details on backend nodejs with the GET request in angular

I am unable to fetch the query parameters of frontend GET request, on the backend side.
I tried using url and query. I need to fetch the query on the nodejs side.
Kindly suggest a suitable method that would help me get the details on GET request using axios.
code -
component.ts - angular file
googleSearch(googleText){
let params = new HttpParams();
params = params.append('q', googleText.trueLocation);
return new Promise((resolve, reject) => {
this.httpClient.get("http://localhost:3003/seekSearchApi" , ({params:params}))
.pipe(map(Response => Response))
.pipe(catchError(this.errorHandler))
.subscribe((res: Response) => {
this.writeItOutput = res;
resolve(this.writeItOutput);
});
})
}
errorHandler(error: HttpErrorResponse) {
return throwError(error.message || 'server Error');
}
}
server.js- express file
app.use('/seekSearchApi', require('./server/nodejs-serverapi'));
applicationserver.js - nodejs file
function seekSearchApi(req,res) {
var query = require('url').parse(req.url,true).query;
console.log("req.query.q", query.q); //no response
console.log("Inside seekSearchApi");
axios({
method: 'get',
url: 'https://serpapi.com/search.json?',
data: {
api_key: "xxxx",
q:query.q
hl: "en",
gl: "us",
google_domain: "google.com"
}
}).then((response) => {
res.send(stringify(response))
}, (error) => {
console.log(error);
});
I figured it out .
On node side.
applicationserver.js
function seekSearchApi(req,res) {
var url_data = url.parse(req.url, true);
var query = url_data.query;
var queryData= Object.assign({},query);
console.log("queryData = ", queryData);
::::
}

How to create a session for authentication with fetch API in JS

I have two URLs. The first one is for login post request and the second URL is to call for a json. I can not get the json file from URL, if I am not logged in. How can I create a session so I can do more than one post request or alternatively how can i use JWT or set-cookie for authentication?
const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args));
const login_url = "https://www.example.com/login"
const json_url = "https://www.example.com/users/anastasia"
const data = {"username": "my_username", "password": "my_password"}
const otherParm = {
headers:{"content-type": 'application/json'},
body:JSON.stringify(data),
method:"POST"
};
fetch(login_url, otherParm)
//.then(data=>{return data.json()})
.then(res=>{
console.log(res.headers.get('jwt'))
})
.catch(err=>console.log(err))
The response is:
distinct_id: 156841653654e68w,
jwt: e1616er5hw16e35hw6e5h6eth
fetch(json_url).then(function (response) {
return response.json();
}).then(function (obt) {
console.log(obt);
}).catch(function(error) {
console.error('something went wrong with retrieving the json file');
console.error(error);
});
The response is: 401 Unauthorized

How to send json data to client side from express nodejs

I have an application, where I need to send the form data through XMLHttpRequest. When I send that information over, I then need to validate the form, then send information back to the client based on if the form validates or not. I'm using nodejs with express.
My client side code is:
editor.save().then((output) => {
let formData = new FormData();
const xhr = new XMLHttpRequest();
formData.append('name', document.getElementById('inputProductName').value);
xhr.open('post', '/items/add', true);
xhr.send(formData);
}).catch((error) => {
console.error('Error: ' + error);
return;
}).finally(() => {
// This is where I need to retrieve the validation code and redirect accordingly.
if (success == false) {
window.location.href = '/items/add/failed';
} else {
window.location.href = '/items/add/success';
}
});
My server side code is this:
router.post('/add', (req, res) => {
let form = new formidable.IncomingForm();
form.parse(req, (err, fields, files) => {
if (fields.name.length < 1) { // If the name is empty
res.status(200).json({
success: false,
message: 'Product name must be specified'
});
} else {
res.status(200).json({
success: true,
message: 'Product added successfully'
});
}
});
});
So if the the validation fails, then I want to be able to get the success and message variable through the client end if possible.
Have a look at using fetch API from MDN docs
fetch data via POST
await response
based on response.success act accordingly
Additionally,looking a the server-side code, it doesn't appear necessary that form encoding be used.
Suggest sending the data in json format and have the server check the request.body for the appropriate field to be populated.
pseudo code
editor.save().then(async (output) => {
let formData = new FormData();
formData.append('name', document.getElementById('inputProductName').value);
const response = await fetch(url, {
method: 'POST',
// ... additional form data here, looks like you can send JSON, no need for form encoding
}
if(response.success) {
window.location.href = '/items/add/success';
} else {
window.location.href = '/items/add/failed';
}
}).catch((error) => {
console.error('Error: ' + error);
return;
})
Note that the anonymous function () => {} is now async () => {} to allow await on the fetch call.
async / await

Difference between Python requests POST and axios POST

I am having a difficult time understanding why my API call does not work in axios (relatively new to JS). I have built an API server that takes in an Authorization header with a JWT token.
Here is my POST request workflow in Python:
resp = requests.post('http://127.0.0.1:8000/api/v1/login/access-token', data={'username': 'admin#xyz.com', 'password': 'password'})
token = resp.json()['access_token']
test = requests.post('http://127.0.0.1:8000/api/v1/login/test-token', headers={'Authorization': f'Bearer {token}'})
# ALL SUCCESSFUL
Using axios:
const handleLogin = () => {
const params = new URLSearchParams();
params.append('username', username.value);
params.append('password', password.value);
setError(null);
setLoading(true);
axios.post('http://localhost:8000/api/v1/login/access-token', params).then(response => {
console.log(response)
setLoading(false);
setUserSession(response.data.access_token);
props.history.push('/dashboard');
}).catch(error => {
setLoading(false);
console.log(error.response)
if (error.response.status === 401) {
setError(error.response.data.message);
} else {
setError("Something went wrong. Please try again later.");
}
});
}
// the above works fine
// however:
const [authLoading, setAuthLoading] = useState(true);
useEffect(() => {
const token = getToken();
if (!token) {
return;
}
axios.post(`http://localhost:8000/api/v1/login/test-token`, {
headers: {
'Authorization': 'Bearer ' + token
}
}).then(response => {
// setUserSession(response.data.token);
console.log('we made it')
setAuthLoading(false);
}).catch(error => {
removeUserSession();
setAuthLoading(false);
});
}, []);
if (authLoading && getToken()) {
return <div className="content">Checking Authentication...</div>
}
// RETURNS A 401 Unauthorized response...
What is different about the two above requests? Why does the axios version return different results than requests?
In my API, CORS have been set to *, and I know that the token within Axios is being saved properly in sessionStorage.
Any ideas?
As far as I can see you are passing your username and password in axios as params and as body data in your python request, I am not sure if your backend expects it as params or body data but try changing const params = new URLSearchParams(); to
const params = new FormData(); if the problem is that the backend isn't getting the body data it needs. The best thing I could recommend is checking your browser network tab and seeing what exactly the problem is when you hit your server.

Categories