RESTful login using ajax and node.js - javascript

I'm struggling with a rather simple approach to login to a server and later on to ensure that I'm still logged in, I'm sending a GET request to receive my user name. I'm using a little node.js server and a single page object using JQuery.
// prints User name to the console if logged in
function getUserName() {
$.ajax({
url: "http://localhost:4730/login",
type: "GET",
dataType: "json",
success: function (resJson) {
$.each(resJson, function (i, userName) {
console.log(userName);
});
},
error: function (xhr, status) {
console.log("Sorry, there was a problem!");
}
});
}
// login a known user
function login(name, password) {
var userData = {
name: name,
password: password
};
$.ajax({
url: "http://localhost:4730/login",
type: "POST",
dataType: "json",
data: userData,
error: function (xhr, status) {
console.log("Sorry, there was a problem!");
},
complete: function (xhr, status) {
console.log(xhr);
}
});
}
My server (node.js) is generating a dummy user id and checks this one when the next GET request arrives.
// Checks if the user is logged in and returns its name or an empty string
app.get('/login', function (req, res) {
if (typeof (req.session.user_id) == "number") {
res.json(users[req.session.user_id].name);
return;
}
res.json("");
});
// Check if the user exists and if the password is correct
app.post('/login', function (req, res) {
var post = req.body;
var user = findUser(post.name);
if( !!user && post.password == user.password)
{
req.session.user_id = user.id;
res.json(true);
return;
}
res.json(false);
});
My user is already registered and the login request returns successfully. But after logged in, my GET request to getUserName returns an empty string. What I don't get is where is the session.user_id set? Doesn't the client has to now it?
I have already seen couple of solutions by using passport, etc but I would like to understand the basic of the session/user id handling.
Thanks a lot for your help

Here:
var post = req.body; // the request body with username & password.
var user = findUser(post.name); // you are extracting the username
if( !!user && post.password == user.password)
//---------------------------^^^^^^^^^^^^^-----this isn't available in it.
In your var post you have all the posted request body, which has name & password.
In your var user you are extracting the name out of posted values.
Now in your if condition i don't think user.password is available.
Either make sure you would return the object from findUser(post.name) or change it to: post.password != ""

Related

Javascript Object Undefined - Jquery + Node JS

I'm facing this problem and I'm a newbie with Javascript and NodeJS, below I have this code at my Route on /update/:id
controller.save = (req, res) => {
const data = req.body
const name = req.body.name
const cpf = req.body.cpf
req.getConnection((err, connection) => {
const query = connection.query(
`INSERT INTO clientes(Nome, CPF)
VALUES('${name}','${cpf}')`,
data,
(err, clientes) => {
res.json(clientes)
}
)
})
}
and I have a form that have a Button called "Update", when I click , the AJAX made this .
$(document).on("click", ".update", function() {
var user_id = $(this).attr("id")
$.ajax({
url: "/update/" + user_id,
method: "GET",
dataType: "json",
success: function(to) {
alert(to)
}
})
})
I'm receive a alert [Object Object], when I go to my Network response I have this:
[{"ID":5,"Nome":"tobiaas","CPF":"107"}]
when I change alert to alert(to.Nome), I receive a alert Undefined
I don't wanna use .map, because i thing that this is a simple way to made work .
You are receiving an array as the response, Array.Nome does not exists, your output is normal.
You need to get the item with response[0] or response.pop() to access it:
success: function(response) {
const to = response[0]
alert(to.Nome)
}
For more info on javascript array access, see W3School

How to redirect url after setting cookie using express?

This is my login code in express router:
if (password === realpassword) {
res.cookie('thecookie', 'somethingliketoken');
res.redirect(302, '/somepages');
} else {
res.status(403).end();
}
I want to set the cookie so that the /somepages can recognize who is this user.
But I got error Error: Can't set headers after they are sent.
I had already tried return res.redirect(302, '/somepages');. The query to /somepages had be sent correctly but the page still stayed in my /login.
Please help.
I think I got the reason.
I posted the username and password using AJAX so the 302 redirect was sent to the AJAX query and yes it redirected successfully but it was for the AJAX query, not for the page, that was why the second query was received but the page didn't change.
this.$http({
url: '/userLogin',
method: 'post',
data: {
username: this.username,
password: SHA3(this.password, {outputLength: 256}).toString(),
},
}).then(res => {
console.log(res);
this.hintColor = '#00bdd8';
this.hint = 'success';
}).catch(err => {
this.hintColor = 'red';
if (err.response.status == 403) {
this.hint = 'mismatch';
} else {
this.hint = '500err';
}
});
I think it may should not be used like this.
Will using window.location instead.
If there are any other ways, I really appreciate your help.
I have done something like this in my login post request, and its working for me.
app.post('/index',function(req,res){
var uname = req.body.Username;
var pwd = req.body.Password;
if(uname && pwd === 'admin'){
var token = jwt.sign( { username: uname }, 'q1W2e3R4t5Y6u7I8o9P',{ expiresIn: '1m' }
);
res.cookie('auth',token);
res.redirect('home');
console.log('Authentication is done successfully.....');
console.log(token);
}
});

Ajax- Why do I get an error function instead of success?

I don't understand why is my code running the error function instead of success. I keep getting this from my console.log
Object {readyState: 0, getResponseHeader: function, getAllResponseHeaders: function, setRequestHeader: function, overrideMimeType: function…}
I could not think of any reason why won't it execute my logic so I tried putting a redirect in my error function and this is what I get
Object {readyState: 0, getResponseHeader: function, getAllResponseHeaders: function, setRequestHeader: function, overrideMimeType: function…}
Basically the same thing happened so as of now I don't really have an idea as to what my problem is after editing the windows to window.
This is my code in js
function login(){
var username = document.getElementById("userID").value;
var password = document.getElementById("Password").value;
var postData = { "userID": username, "Password": password };
var postJSON = JSON.stringify(postData);
$.ajax({
url: "http://localhost:3000/api/login", // server url
type: "POST", //POST or GET
contentType: "application/json",
data: postJSON, // data to send in ajax format or querystring format
datatype: "JSON",
success: function(response) {
alert('success');
console.log(response);
window.location.replace("http://localhost/index.html");
},
error: function(response) {
alert('error');
console.log(response);
window.location.replace("http://localhost/index.html");
}
});
}
This is my html code. I am using onclick.
<input class="button" type="submit" id="submit" value="Log In" onclick="return login()"/>
So exactly what went wrong in my code? I am trying to call my login api (localhost:3000/api/login) through ajax with post which would then check mongodb for correct entries and output Login Success which then redirect to another page if input is correct and stay on the same page if input is wrong by giving output "Invalid Login ID or Password".
UPDATE:
Server Side Code
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017/myproject';
var authenticate = function(db, req, callback){
var cursor = db.collection('LoginID').find({"_id" : req.body.userID,
"Password" : req.body.Password
}).count(function(err,doc){
if(err) return callback(err);
if(doc == 0){
console.log('Invalid Login ID or Password');
return callback(null, doc);
} else {
console.log('Login Success');
return callback(null, doc);
}
});
}
module.exports = {
postCollection : function(req,res){
var username = req.body.userID;
var Password = req.body.Password;
//var createdDate = "<b>" + day + "/" + month + "/" + year + "</b>"
MongoClient.connect(url, function(err, db) {
//assert.equal(null, err);
if(err) {
res.send(err);
res.end();
}
authenticate(db, req, function(err,doc) {
if(err)
res.send(err);
else{
if(!doc){
res.send( ' Invalid Login ID or Password ' );
res.end();
} else {
res.send("Login success")
res.end();
}
}
db.close();
});
});
}
}
If I remember correctly, the success callback is only called if the HTTP return code is 2xx.
If you send back a redirection, it is considered as an error.
The documentation mentions it:
If the request is successful, the status
code functions take the same parameters as the success callback; if
it results in an error (including 3xx redirect), they take the same
parameters as the error callback.
From http://api.jquery.com/jquery.ajax/, statusCode section.
Moreover, you have to be careful: if an AJAX request receives a 302 response, it won't do a redirection: that is the user agent of your web browser (classic navigation) that does that automatically, but for XHR/AJAX, you have to implement it.

Issue with rendering page after performing delete function

exports.deleteItem = function (req, res)
{
var query = req.params.id;
var cart = req.session.items;
var index;
_.each(cart,function (ticket)
{
if(ticket.id === query)
{
index = cart.indexOf(ticket);
cart.splice(index,1);
}
return res.redirect(303, '/cart');
});
};
I am using this function in my routes to perform a delete operation. It works for the first few items on my list, then suddenly stops and gives me the error "Can't set headers after they are sent."
$(document).ready(function() {
$('.delete-from-cart').click(function(event)
{
$target = $(event.target);
$.ajax({
type: 'DELETE',
url: '/cart/remove/' + $target.attr('data-item-id'),
data: {
_csrf: $target.attr('data-csrf')
},
success: function(response)
{
$target.parent().parent().remove();
Materialize.toast('Ticket Removed', 4000);
window.location.href = '/cart';
},
error: function(error)
{
Materialize.toast('Error', 4000);
console.log(error);
}
});
});
});
A single request was made, which means a single response should occur.
When you execute the _.each function I'm guessing that it works if there is one item but fails when there are multiple? This is because you are trying to send multiple responses when only one is permitted.
A good explanation for this can be found here: Error: Can't set headers after they are sent to the client

Node.js Page Redirect on AJAX login? With a function call after redirect?

The '/stories' page is user-specific and requires valid login credentials.
Validation is accounted for with node, server-side, and properly logs before the redirect, but does not redirect to the stories page..
This seems to be because "You can't make a redirection after an AJAX. You need to do it yourself in Javascript", but the code in the first answer to this question seems somewhat incomplete..for the succcess call..
Also, how can a subsequent function (refreshStories) be called on success after the redirect?
Here's the AJAX:
if (loginUsername.length != 0) {
console.log('there is a login: ' + loginUsername);
// make an ajax call
$.ajax({
dataType: 'json',
data: AjaxLoginData,
type: 'post',
url:"http://localhost:4200/api/v1/users",
success: (data, textStatus, jqXHR) ->
if typeof data.redirect == 'string'
window.location = data.redirect
success: refreshStories,
error: foundError
});
Node.js + Express4
router.route('/users')
// log in a user (accessed at POST http://localhost:4200/api/v1/users)
.post(function(req, res) {
var username = req.body.loginUsername;
var password = req.body.loginPassword;
authenticateUser(username, password, function(err, user){
console.log('authenticate user..');
if (user) {
console.log('yes user');
// subsequent requests will know the user is logged in
req.session.username = user.username;
console.log('set session username to: ' + req.session.username);
// res.redirect('/stories');
res.send({redirect: '/stories'});
console.log('user logged in .. redirect to stories');
} else {
console.log('user authentication badCredentials error..');
res.render('index', {badCredentials: true});
}
});
});
Try this
if (loginUsername.length != 0) {
console.log('there is a login: ' + loginUsername);
// make an ajax call
$.ajax({
dataType: 'json',
data: AjaxLoginData,
type: 'post',
url:"http://localhost:4200/api/v1/users",
success: (data, textStatus, jqXHR) ->
if (typeof data.redirect == 'string')
window.location.replace(window.location.protocol + "//" + window.location.host + data.redirect);
error: foundError
});
window.location.replace(...) will best simulate an HTTP redirect
How to redirect to another webpage in JavaScript/jQuery?
For your 'refreshStories' stuff, you should just refresh Stories when you go to '/stories'

Categories

Resources