I am trying to use a username and password to login in website and get the session token.
The username and password actually works and it logins in the system but the problem is that the session token shows inside the error response.
Is it a good idea to parse the error and get session token?
Why its shown inside the error?
Here is the code:
const rp = require('request-promise')
const options = {
method: 'POST',
uri: 'https://superset.simurgbilisim.com/login/',
json: true,
form: {
username: 'test',
password: 'test'
}
};
rp(options)
.then(function(body) {
console.log(body);
})
.catch(function(err) {
console.log(err);
});
Related
I have a BE which is validating my sign in data then I am storing them in cookies like below:
exports.signIn = async (req, res) => {
const { email, password } = req.body;
const user = await User.findOne({
email: email,
});
if (user === null) res.status(400).json({ error: 'No such user' });
let isCorrectUser = await user.authenticatePassword(password);
if (isCorrectUser) {
const token = jwt.sign({ id: user._id }, process.env.SECRET);
// setting httpsOnly:true so that it is automatically sent from front-end
res.cookie('token', token, { httpOnly: true });
res.json({
message: 'User has been successfully logged in',
body: {
token: token,
user: {
id: user._id,
email: user.email,
role: user.role,
},
},
});
} else {
res.status(400).json({ message: 'Incorrect password' });
}
};
I read that if we use httpOnly while making a post request we dont need to send the header with bearer token.
this is my auth helper in front-end to fetch users(only if signed in)
const newData = await fetch(
`http://localhost:3001/api/user/${userData.data.body.user.id}`,
{ credentials: 'include' } // could also try 'same-origin'
);
But I need to specifically set bearer token from sign in explicitly in the above request for it to work. I have read a lot of similar questions but it did not work. Please advise me how to work around.
I'm not sure how to check if the values match with the MongoDB data. I am using PUT and trying to use findOneAndUpdate to check if the values match.
<script>
const logindetails = new Vue({
el: '#logindetails',
data: {
email: "",
password: "",
on: Boolean
},
methods: {
login: function (e) {
e.preventDefault();
const log = {
email: this.email,
password: this.password,
}
const options = {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(log)
};
fetch('http://localhost:3000/users/${this.email}/${this.password}',
options).then(response => {
[...]
</script>
This is the server code (it successfully connected to MongoDB) :
app.put('/students/:email/:password', (req, res, next) => {
console.log("login");
res.setHeader("Content-Type", "application/json");
db.collection('users').findOne({email: (req.params.email), password: (req.params.password)},
{$set: {on: true}})
.then(results => res.send(results))
.catch(err => res.send(err))
});
I personally don't think it is a good idea to put your username and password as query string, because it hurts the restful api convention. It wouldn't make sense to use a put request if there is no body being pass. Also, a post request would make more sense in a login situation .Anyway I digress, here are the usual steps to doing authentication.
1. (Client-Side) Send the email and password in the body of the fetch request
//something like this
const body = { email, password };
const response = await fetch(
"http://localhost:5000/authentication/login",
{
method: "POST",
headers: {
"Content-type": "application/json"
},
body: JSON.stringify(body)
}
);
2.(Server-Side - make sure you to use app.use(express.json()) to access req.body)
//defining middleware to access req.body
app.use(express.json());
app.post("/authentication/login", async(req,res) =>{
//1. destructure email and password
const {email, password} = req.body
//2. check if user doesn't exist
const user = await db.user.find({user_email: email})
if(!user){
return res.status(401).send("User does not exist");
}
//3. Check if password is the same as the password in the database
if(password !== user.password){
return res.status(401).send("Wrong Credential")
}
//4. This is up to you when the user is authenticated
res.json(`Welcome back ${email}`);
})
I am struggling to make a login system using JSON web tokens.
I have made the login (client side) that calls to my server.js file.
This is the login through the client side Below is my handle submit function that calls the server.js login route.How would I use a token here?
handleSubmit(e) {
e.preventDefault();
if (this.state.email.length < 8 || this.state.password.length < 8) {
alert(`please enter the form correctly `);
} else {
const data = { email: this.state.email, password: this.state.password };
fetch("/login", {
method: "POST", // or 'PUT'
headers: {
Accept: "application/json, text/plain, */*",
"Content-Type": "application/json"
},
body: JSON.stringify(data)
})
.then(data => {
console.log("Success:", data);
})
.catch(error => {
console.error("Error:", error);
});
}
}
catch(e) {
console.log(e);
}
This is the login route for my server.js. As you can see I have assigned a jwt but how would I send this back to my login form and utilise it for protected routes.
app.post("/login", async (req, response) => {
try {
await sql.connect(config);
var request = new sql.Request();
var Email = req.body.email;
var Password = req.body.password;
console.log({ Email, Password });
request.input("Email", sql.VarChar, Email);
request.input("Password", sql.VarChar, Password);
const result = await request.execute("dbo.LoginUser");
if (result.recordsets[0].length > 0) {
console.info("/login: login successful..");
console.log(req.body);
const token = jwt.sign({ user: Email }, "SECRET_KEY", {
expiresIn: 3600000
});
var decoded = jwt.verify(token, "SECRET_KEY");
console.log(decoded);
response.status(200).json({
ok: true,
user: Email,
token: token
});
console.log(token);
} else {
console.info("/login: bad creds");
response.status(400).send("Incorrect email and/or Password!");
}
} catch (err) {
console.log("Err: ", err);
response.status(500).send("Check api console.log for the error");
}
});
Essentially all I want is for my submit handler to be called for login. Server returns a jwt token which can then be used to verify other routes.
There are two ways to route:
Use React-Redux and react-router.
Save the fetched JWT token into localStorage and use to validate route within your routes component.
I would recommend in using React-Redux / React-router for protected routing.
Here is a video link to Build Real Web App with React by
Rem Zolotykh
This will help you.
i am beginner in ajax and i decided to use jquery ajax for this moment , and before using ajax i created simple login / signup pages and i used bodyparser for requests
and when password or username is incorrect it reloads and then sends response to user that one of them is incorrect, and as i know ajax works without reload and
how can i add ajax when info is incorrect while login here is code
app.post('/login',
async (req, res) => {
try {
const { username, password } = req.body;
const user = await User.findOne({ username, password }).select('-password').lean();
if (!user) {
res.send('User: ' + username + ' not registered');
return;
}
req.session.user = user;
res.redirect('/dash')
return res.status(200).send('Session ID: ' + req.sessionID);
}
catch (error) {
res.status(500).send(error.message);
}
});
Try some thing like this:
$('#login-button').on('click', function(event) {
event.preventDefault();
var username = $('#username').val(), password = $('#password').val();
$.ajax({
type: 'POST',
data: JSON.stringify({ username: username, password: password }),
contentType: "application/json; charset=utf-8",
url: 'http://localhost:8000/login',
success: function(sessionID) {
console.log(sessionID);
},
error: function(xhr, status, err) {
var errMsg = xhr.responseText; // Your error msg
$('#errMsg').html(errMsg);
}
});
});
I have two routes in my node js app: users & records
In the users route I am getting the token on /login path:
users.post('/login', function(req, res) {
const email = req.body.email;
const password = req.body.password;
var token = '';
connection.query(`SELECT * FROM ${process.env.USER_TBL} WHERE EMAIL = ?`, [email], function(err, results, fields) {
if (err) {
res.status(200).json({'message' : err, 'token' : token})
}
if (results.length > 0) {
bcrypt.compare(password, results[0].PASSWORD).then(function(match) {
if (match == true) {
token = jwt.sign(JSON.parse(JSON.stringify(results[0])), process.env.SECRET_KEY, {
expiresIn: 5000
})
res.status(200).json({'message' : 'User verified', 'token' : token})
} else {
res.status(200).json({'message' : 'Email or Password does not match', 'token' : token})
}
})
} else {
res.status(200).json({'message' : 'Email does not exists', 'token' : token})
}
})
connection.end(err => {
if(err) console.log(err);
})
})
In my second route records I am making a request to path /addNewRecord,
records.post('/addNewRecord', function(req, res) {
//need the token to authenticate the request
});
here I need the token generated from /login route to send in the hrader and authenticate my request.
but I am understand how can I pass token value from users route to records route.
When you login you transmit your token to the user, capture that token and put it into local storage on the client. Then it available for the next call to the server.
localstorage.setItem('token', token)
When making your next server request you would use the stored token in your header.
$.ajax({
url: "URL",
method: "POST",
headers: {
'authorization': localstorage.getItem('token'), //YOUR TOKEN GOES HERE
'anotherHeader': 'headerValue2'
}
});
Then you can capture the token from the next request to verify it is valid
records.post('/addNewRecord', function(req, res) {
let token = req.headers['authorization']
});
You can't pass a token between server side code in that manner. It has to be sent from the client. Whenever /login is called from the client side and it receives a response, you can then store the token from that response on the client side. When calling /addNewRecord simply add the token in the header of the request on the client side and it can be accessed by inspecting req.get(headerName) or req.headers on the server side.