I am working on a simple login using POST Fetch in Reactjs with NodeJs API. The code is working good and redirect the page when we login using correct username and password but the problem is when using fake username. I got the error in console.log with Promise : "Rejected". And I still can not figure it why
Here is the code in login.js
async SubmitLogin(event){
event.preventDefault();
//debugger;
console.log(this.state)
await fetch(`http://localhost:4000/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify(this.state)
})
.then ((response) => {
if (!response.ok) {
throw Error(response.statusText);
}
// then Read the response as json.
else {
let result = response.json();
console.log(result)
if(result === 'Invalid'){
console.log(response)
alert('Invalid User');
//this.props.history.push('/login');
}
else {
alert('Login Sucessfull');
this.props.history.push('/home');
}
}
})
.catch((err) => {
console.error();
})
}
in my server.js, I used express-session like this:
//sales login
app.post('/login', jsonParser, (req, res) => { //jsonParser,
let username = req.body.username;
let password = req.body.password;
console.log("req: ",req.body);
if (username && password) {
dbConn.query(`SELECT * FROM user_tbl WHERE username = ? AND password = ?`, [username, password], (err, results, fields) => {
if (results.length > 0) {
req.session.loggedin = true;
req.session.username = username;
res.redirect('/home');
console.log(results)
console.log("req: ", req.body);
} else {
res.send('Incorrect Username and/or Password!');
}
res.end();
});
} else {
res.send('Please enter Username and Password!');
res.end();
}
});
app.get('/home', (req, res) => {
if (req.session.loggedin) {
res.send('Welcome back, ' + req.session.username + '!');
} else {
res.send('Please login to view this page!');
}
res.end();
});
and this is the result I got in console:
hopefully my question is clear.
I think your response doesnt come json format.You cant parse string to json.
Your response should be like this res.send({success:false , message : "Incorrect Username and/or Password!"})
After many suggestions and anwers, finally I can figure out how to solved this problem. Here is the code in login.js
//submit function
async SubmitLogin(event){
event.preventDefault();
console.log(this.state)
await fetch(`http://localhost:4000/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify(this.state)
})
.then ((response) => {
if(response.status === 401) {
throw new Error('Unauthorized');
}
//return response.json();
})
.then((result) => {
console.log(result);
this.props.history.push('/home');
alert('Login Sucessfull');
})
.catch((err) => {
console.log();
})
}
and in the backend, I didn't change anything.
Related
In my nav.svelte component I have:
{#if $session.token}
${JSON.stringify($session.token)} - ${JSON.stringify($session.token.username)}
{/if}
In login.svelte:
const { session } = stores();
let username, password;
async function onLogin(username, password){
const response = await fetch(`auth/login`, {
method:"POST",
headers:{ 'Content-Type': 'application/json' },
body: JSON.stringify({"username":username,"password":password})
})
if (response.ok) {
const json = await response.json();
session.set({ token: json });
$session.token = json;
goto("/");
} else {
throw new Error(response);
}
}
login.js handler:
req.session.token = user; //parsed.token;
console.log(`req.session.token: ${JSON.stringify(req.session.token)}`);
res.writeHead(200, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify({ token: user }));
server.js:
sapper.middleware({
session: (req, res) => {
console.log(`% req.session.token: ${JSON.stringify(req.session.token)}`);
return ({
token: req.session.token
})}
})
The output in nav.svelte is:
${"token":{"_id":"kjbLgeU8k3GPr6jBd8NkCj","username":"matt123","password":"$2b$10$aXMJc64o9W166OL12CG/A.lWyuB9zdPkaNUsze3Lch6Z2khHaTKY.","access":"user"}} - $undefined
Notice that the data is there, but username outputs undefined. I believe I am doing something wrong but it is obscure.
Added an issue to the tracker on sapper project:
https://github.com/sveltejs/sapper/issues/1711
I'm trying to filter overlap validation for SignUp email.
in my api.js
const token = JSON.parse(localStorage.getItem('token'));
const api = axios.create({
baseURL: baseURL, // already set our base URL
headers: {
Authorization: `Bearer ${token}`,
'Access-Control-Allow-Origin': '*',
}
});
and in my authService.js
const register = (countryCode, name, email, password) => {
return axios
.post('/auth/signup', {
countryCode,
name,
email,
password,
})
.then((response) => {
if (response.headers.authorization) {
console.log(response);
localStorage.setItem('user', JSON.stringify(response.headers.authorization));
}
return response.headers.authorization;
});
};
const login = (email, password) => {
api
.post('/auth/signin', {
email,
password,
})
.then((response) => {
if (response.headers.authorization) {
localStorage.setItem('user', JSON.stringify(response.headers.authorization));
}
return response.data;
});
};
const checkEmail = (email) => {
return api.get('/public/email', { email }).then((response) => {
if (response.data.exist === true) {
return localStorage.getItem('user', JSON.stringify(response.data));
}
return response.data;
});
};
This checkEmail will be in the SignUp.js
for onChange={emailChange}
const onChangeEmail = (e) => {
const email = e.target.value;
if (!email.includes('#')) {
setEmailError('Invalid email');
} else if (email.includes('#')) {
setEmailError(null);
}
AuthService.checkEmail(email).then(
(response) => setEmailError('Already Registered Email'),
(error) => {
console.log(error);
}
);
setEmail(email);
};
after this code,
in the console
it error
Error: Request failed with status code 401
at createError (createError.js:16)
at settle (settle.js:17)
at XMLHttpRequest.handleLoad (xhr.js:62)
I think inn the api.get(URl, {something})
that {something} is wrong but I don't have any idea for hours...
what can I do for this error??
you can't send body parameter in GET , for that POST,PUT will work,
to send with GET then attach data to the GET url.
example
if your using node server at backend then
api.get('/public/email/'+email).then((resp)=>{
log(resp);
}
collect the data using
router.get("public/email/:youremail",(req,res)=>{
req.param.youremail
}
I'm doing requests to my API server to authenticate a user, that's not the problem. The problem is that I don't know why my async function doesn't return anything, and I get an error because the data that I want from this function is undefined.
Don't worry if the error management is ugly and in general I can do this better, I'll do that after fixing this problem.
Utils.js class
async Auth(username, password) {
const body = {
username: username,
password: password
};
let req_uuid = '';
await this.setupUUID()
.then((uuid) => {
req_uuid = uuid;
})
.catch((e) => {
console.error(e);
});
let jwtData = {
"req_uuid": req_uuid,
"origin": "launcher",
"scope": "ec_auth"
};
console.log(req_uuid);
let jwtToken = jwt.sign(jwtData, 'lulz');
await fetch('http://api.myapi.cc/authenticate', {
method: 'POST',
headers: { "Content-Type": "application/json", "identify": jwtToken },
body: JSON.stringify(body),
})
.then((res) => {
// console.log(res);
// If the status is OK (200) get the json data of the response containing the token and return it
if (res.status == 200) {
res.json()
.then((data) => {
return Promise.resolve(data);
});
// If the response status is 401 return an error containing the error code and message
} else if (res.status == 401) {
res.json()
.then((data) => {
console.log(data.message);
});
throw ({ code: 401, msg: 'Wrong username or password' });
// If the response status is 400 (Bad Request) display unknown error message (this sould never happen)
} else if (res.status == 400) {
throw ({ code: 400, msg: 'Unknown error, contact support for help. \nError code: 400' });
}
})
// If there's an error with the fetch request itself then display a dialog box with the error message
.catch((error) => {
// If it's a "normal" error, so it has a code, don't put inside a new error object
if(error.code) {
return Promise.reject(error);
} else {
return Promise.reject({ code: 'critical', msg: error });
}
});
}
Main.js file
utils.Auth('user123', 'admin')
.then((res) => {
console.log(res); // undefined
});
Your Async function must return the last promise:
return fetch('http://api.myapi.cc/authenticate', ...);
or await the result and return it:
var x = await fetch('http://api.myapi.cc/authenticate', ...);
// do something with x and...
return x;
Notice that you don’t need to mix promise syntax (.then) with await. You can, but you don’t need to, and probably shouldn’t.
These two functions do exactly the same thing:
function a() {
return functionReturningPromise().then(function (result) {
return result + 1;
});
}
async function b() {
return (await functionReturningPromise()) + 1;
}
await is not to be used with then.
let data = await this.setupUUID();
or
let data=null;
setupUUID().then(res=> data = res)
I would try something like this:
const postReq = async (jwtToken) => {
const body = {
username: username,
password: password,
};
try {
const res = await fetch('http://api.myapi.cc/authenticate', {
method: 'POST',
headers: { "Content-Type": "application/json", "identify": jwtToken },
body: JSON.stringify(body),
})
if (res) {
if (res.status == 200) {
return res.json();
} else if (res.status == 401) {
const data = res.json();
console.log(data.message)
throw ({ code: 401, msg: 'Wrong username or password' });
} else if (res.status == 400) {
throw ({ code: 400, msg: 'Unknown error, contact support for help. \nError code: 400' });
}
}
} catch (err) {
console.error(err)
}
};
const Auth = async (username, password) => {
const jwtData = {
"origin": "launcher",
"scope": "ec_auth"
};
try {
const req_uuid = await this.setupUUID();
if (req_uuid) {
jwtData["req_uuid"] = req_uuid;
const jwtToken = jwt.sign(jwtData, 'lulz');
return await postReq(jwtToken);
}
} catch (err) {
console.error(err);
};
}
I have a login form that sends data to an Express.js backend using fetch. On the client side, when I want to display the results of the fetch call when it completes nothing is displayed (and it never reaches the data callback). I don't seem to be getting any errors, but I know that the data is successfully being sent to the backend.
Here's the Express.js server code:
const express = require('express');
const User = express.Router();
const bcrypt = require('bcrypt');
const user = require('../Models/user');
this is edited
function loginRouteHandler(req, res) {
user.findOne(
{
where: {
userName: req.body.userName,
},
},
)
.then((data) => {
if (bcrypt.compareSync(req.body.password, data.password)) {
req.session.userName = req.body.userName;
req.session.password = req.body.password;
console.log(req.session);
res.status(200).send('Success!');
} else {
res.status(400).send('some text');
}
});
}
User.route('/').get(getRouteHandler);
User.route('/register').post(postRouteHandler);
User.route('/login').post(loginRouteHandler);
module.exports = User;
And here's the fetch call:
fetch('http://localhost:4000/login',{
method: 'POST',
headers: {
'Accept': 'application/json,text/plain, */*',
'Content-Type': 'application/json'
},
body: JSON.stringify({
userName: this.state.userName,
password: this.state.password,
}),
}).then((response)=>{
if(response.ok){
console.log(response)
}
else {
console.log("a problem")
}
}).then((data)=>{
console.log(data)
});
In your loginRouteHandler, if the bcrypt compare succeeds nothing is returned in the response. So in the first branch of the if statement, put res.send('Success!') or something similar.
Here's an example:
function loginRouteHandler(req, res) {
user.findOne(
{
where: {
userName: req.body.userName,
},
},
)
.then((data) => {
if (bcrypt.compareSync(req.body.password, data.password)) {
req.session.userName = req.body.userName;
req.session.password = req.body.password;
console.log(req.session);
res.status(200).send('Success!');
} else {
res.status(400).send('some text');
}
});
}
UPDATE: you're also not getting the output of the fetch response with .text() or .json(). You have to update the fetch call to the following:
fetch(/* stuff */).then((response)=>{
if(response.ok){
console.log(response)
}
else {
console.log("a problem")
}
return response.text()
}).then((data)=>{
console.log(data)
});
Remove ok from response.ok
Remove .then((data)=>{ console.log(data) });
And check console log.
}).then((response)=>{
if(response){
console.log(response)
}
else {
console.log("a problem")
}
}).then((data)=>{
console.log(data)
});
is a bit of a situation
after simple login
i'v tried to properly handle the server error response but at first i thought it will be simple. i was wrong.
the press login function rely on the login function to pass the login status to check if the user is or not logged.
in a way the code works but it will be great if can get the server response and display.
i've tried to use catch or get a response from the login function. either way still not getting the responde. please someone could spare a hint related to this of problem?
login handler on login.jsx
pressLogin() {
return auth
.login(this.state.email, this.state.password)
.then(response => {
this.props.updateAuth();
let res = response.text();
if (response.login_status == false) {
let errors = res;
throw response.json();
//this.setState({ error: errors });
} else {
// console.log('asdasd')
// this.forceUpdate();
this.setState({ redirectToHome: true });
}
})
.catch(errors => {
return errors;
console.log("Error");
});
}
}
if i set a state in catch just setting a string works but it will be great if can get the server side errors
the login on auth.js
login(email, password) {
return fetch("/login", {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify({
email: email,
password: password
})
})
.then(resp => {
if (resp.status >= 200 && resp.status < 300) {
return resp.text();
} else {
throw resp.json();
}
})
.then(response => {
if (!response.status) {
window.localStorage.setItem("auth_token", response);
return {
login_status: true
};
} else {
return {
login_status: false
};
}
})
.catch(error => {
console.log("Error" + error);
return {
login_status: false
};
});
},