Reputation: 407
I'm trying to implement a login system where an user can register to a website, and then sign in with his account. Once the user is logged in, he can edit his personal information.
To check if the user is logged in, I'm trying to set req.session.isLoggedIn
to true
and then check if that value is true to access some areas of the website. The thing is that just after I signed in, I print the value of req.session
and I see my just setted valued, but after that, when I try to check the value of req.session.isLoggedIn
in another route, I get no value.
Here's my code:
const express = require('express');
const app = express();
var { Client } = require('pg');
var bcrypt = require('bcrypt');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var cors = require('cors');
var path = require('path');
var session = require('express-session');
var url = require("url");
app.use(cors());
app.use(express.static(path.join(__dirname, 'client/build')));
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 600000000 }}))
const client = new Client({
user: 'xxxxxxxxxxxxx',
host: 'xxxxxxxxxxxxx',
password: 'xxxxxxxxxxxxxxx',
database: 'xxxxxxxxxxxxxx',
port: 5432,
ssl: true
})
client.connect();
/*Rutas*/
/*Seleccionar huellas pertenecientas a una cierta categoria*/
app.get('/api/huellas/:categoria', (req, res) => {
client.query('SELECT * FROM huellas WHERE categoria = $1 AND activo = TRUE', [req.params.categoria], (err, query) => {
if (err) {
console.log(err.stack);
} else {
res.json(query.rows);
}
});
});
/*Listar todas las huellas*/
app.get('/api/mostrarHuellas', function(req, res, next) {
client.query('SELECT * FROM huellas', (err, query) => {
if (err) {
console.log(err.stack);
} else {
res.json(query.rows);
}
});
});
app.get('/api/buscarHuellas/', function(req, res) {
console.log(req);
console.log("nombre: " + req.query.nombre + " categoria: " + req.query.categoria + " estado: " + req.query.estado);
client.query('SELECT * FROM huellas WHERE (nombre = $1 AND categoria = $2 AND estado = $3) AND activo = TRUE', [req.query.nombre, req.query.categoria, req.query.estado], (err, query) => {
if (err) {
console.log(err.stack);
} else {
res.json(query.rows);
}
});
});
app.post("/api/registro", function(req, res) {
var email = req.body.email;
var password = bcrypt.hashSync(req.body.password, 10);
client.query('INSERT INTO usuarios(email, password, huella) VALUES ($1, $2, $3)', [email, password, req.body.huella], function(err, result) {
if(err) {
//console.log(err.stack);
res.json(err);
}
else {
console.log('row inserted');
res.json("ok");
}
});
});
app.post("/api/login", function(req, res) {
client.query('SELECT * FROM usuarios WHERE email = $1', [req.body.email], (err, query) => {
if (err) {
console.log(err.stack);
} else {
if(bcrypt.compareSync(req.body.password, query.rows[0].password)){
req.session.isLoggedIn = true;
console.log(req.session);
res.json("ok");
}
else{
res.json("clave invalida");
}
res.end();
}
});
});
app.get("/api/logout", function(req, res) {
req.session.destroy();
});
app.get("/api/sessions", function(req, res){
console.log(req.session);
if(req.session.isLoggedIn) {
console.log("logged in!");
}
});
const port = process.env.PORT || 5000;
app.listen(port);
When I access /api/login/
I receive this output in the terminal, I can see isLoggedIn:
Session {
cookie:
{ path: '/',
_expires: 2017-09-05T00:29:19.786Z,
originalMaxAge: 600000000,
httpOnly: true },
isLoggedIn: true }
But after that, when I access /api/sessions/
I receive this output:
Session {
cookie:
{ path: '/',
_expires: 2017-09-05T00:29:21.451Z,
originalMaxAge: 599999999,
httpOnly: true } }
I'm using Nodejs and Expressjs. Also, I'm serving some static file stored in /client/build
, and they are working fine.
Thanks in advance!
EDIT:
Here's what my handle login method looks like, I'm using react and react-router 4:
handleSubmit(event){
event.preventDefault();
fetch('/api/login', {
method: 'post',
headers: {'Content-Type':'application/json'},
body: JSON.stringify({
"email": document.getElementById("email").value,
"password": document.getElementById("pwd").value
})
})
.then(response => response.json())
.then(res => {
switch (res) {
case "clave invalida":
alert("clave invalida");
break;
case "ok":
alert("sesion iniciada");
this.props.history.push("/");
break;
default:
alert("Error. Contacte a un administrador");
break;
}
})
.catch(err => console.log(err));
};
Upvotes: 3
Views: 4348
Reputation: 407
Well, I just found a solution for my problem. I used the solution posted by @ytibrewala here and the comment made by @nlawson here. This is what I did:
Apparently, by default, fetch
method doesn't send cookies, so you need to set the credentials
parameter inside the AJAX call, I did it this way:
handleSubmit(event){
event.preventDefault();
fetch('http://localhost:5000/api/login', {
method: 'post',
credentials: 'include',
headers: {'Content-Type':'application/json'},
body: JSON.stringify({
"email": document.getElementById("email").value,
"password": document.getElementById("pwd").value
})
})
.then(response => response.json())
.then(res => {
console.log(res);
if(res.isLoggedIn){
alert("Signed in");
this.props.history.push("/hueprint");
}
else{
alert("Invalid user or password");
}
})
.catch(err => console.log(err));
};
I used include
because I'm not working with the same origin. More information about the values that the credentials
parameter accepts can be found here
Then, I was facing a CORS issue in my browser, so I changed this on my index.js
file on my back end:
app.use(cors({credentials: true, origin: true}));
Now, everytime I use my handleSubmit method in my website, and I checked the test route that prints req.session
I see my isLoggedIn
parameter properly setted.
I leave my route, for those who want to see it:
app.post("/api/login", function(req, res) {
client.query('SELECT * FROM usuarios WHERE email = $1', [req.body.email], (err, query) => {
if (err) {
console.log(err.stack);
}
else {
if(bcrypt.compareSync(req.body.password, query.rows[0].password)){
console.log("password matches");
req.session.isLoggedIn = true;
req.session.save();
res.send(req.session);
}
else{
console.log("password doesn't match");
req.session.isLoggedIn = false;
req.session.save();
res.send(req.session);
}
}
});
});
Upvotes: 5
Reputation: 2826
You need to send the cookies with the res
object whenever you want to save them. Here is my code and it works. Check it out.
app.use(session({
secret: 'keyboard cat',
resave: true,
saveUninitialized: true,
}))
app.get("/", function(req, res){
if(req.session.views){
req.session.views++;
}else{
req.session.views = 1;
}
res.status(200).send(req.session);
})
app.get("/checkerPage", function(req, res){
console.log(req.session); //it logs the correct data.
res.send("whatever");
})
//post req
app.post("/post", function(req, res){
req.session.user = "myname";
res.send(req.session);
console.log(req.session);
});
my index html
<form action="/post" method="post">
<input type="text" name="myName" value="">
<input type="submit" name="" value="submit">
</form>
Upvotes: 1