我正在尝试实施一个登录系统,用户可以在其中注册网站,然后使用他的帐户登录。一旦用户登录,他就可以编辑他的个人信息。
要检查用户是否已登录,我正在尝试将req.session.isLoggedIn
设置为true
,然后检查该值是否为true以访问网站的某些区域。事情是,在我登录后,我打印req.session
的值,我看到我刚设置的值,但在那之后,当我尝试检查另一条路线中req.session.isLoggedIn
的值时,我没有价值。
这是我的代码:
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);
当我访问/api/login/
时,我在终端中收到此输出,我可以看到isLoggedIn:
Session {
cookie:
{ path: '/',
_expires: 2017-09-05T00:29:19.786Z,
originalMaxAge: 600000000,
httpOnly: true },
isLoggedIn: true }
但在那之后,当我访问/api/sessions/
时,我收到了这个输出:
Session {
cookie:
{ path: '/',
_expires: 2017-09-05T00:29:21.451Z,
originalMaxAge: 599999999,
httpOnly: true } }
我正在使用Nodejs和Expressjs。另外,我正在提供存储在/client/build
中的一些静态文件,它们工作正常。
提前致谢!
编辑:
这是我的句柄登录方法的样子,我正在使用react和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));
};
答案 0 :(得分:2)
好吧,我刚刚为我的问题找到了解决方案。我使用了@ytibrewala here发布的解决方案和@nlawson here发表的评论。这就是我所做的:
显然,默认情况下,fetch
方法不会发送Cookie ,因此您需要在AJAX调用中设置credentials
参数,我是这样做的:
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));
};
我使用include
,因为我没有使用相同的来源。可以找到有关credentials
参数接受的值的更多信息here
然后,我在浏览器中遇到了CORS问题,因此我在后端的index.js
文件中更改了此问题:
app.use(cors({credentials: true, origin: true}));
现在,每次我在我的网站上使用handleSubmit方法时,我都会检查打印req.session
的测试路线。我看到我的isLoggedIn
参数已正确设置。
我离开了我的路线,对于那些想要看到它的人:
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);
}
}
});
});
答案 1 :(得分:1)
每当您想要保存时,您需要使用res
对象发送Cookie。这是我的代码,它的工作原理。看看吧。
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);
});
我的索引html
<form action="/post" method="post">
<input type="text" name="myName" value="">
<input type="submit" name="" value="submit">
</form>