【发布时间】:2021-01-31 08:38:24
【问题描述】:
我只是想使用 Express (node.js) 创建一个注销功能。登录和会话检查器功能运行良好,但我似乎无法删除用户的令牌并在单击注销时结束会话。注意:我是在 Mongodb 中存储数据
api 路由 api/secret 本质上是仪表板。当用户点击它时,他们会收到一条消息“Hello + req.email”没有被删除。
我将如何创建功能以完全退出会话?
服务器.js
const express = require("express");
const logger = require("morgan");
const mongoose = require("mongoose");
const routes = require("./routes");
const session = require('express-session')
// const cookieParser = require("cookie-parser");
const bodyParser = require('body-parser')
const morgan = require('morgan')
const User = require('./models/User')
const secret = 'mysecretsshhh';
const jwt = require('jsonwebtoken');
const cookieParser = require('cookie-parser');
const withAuth = require('./middleware');
const PORT = process.env.PORT || 3001;
// Initialize Express
const app = express();
// create application/json parser
const jsonParser = bodyParser.json()
// initialize body-parser to parse incoming parameters requests to req.body
app.use(bodyParser.urlencoded({ extended: true }));
// set morgan to log info about our requests for development use.
app.use(morgan("dev"));
// initialize cookie-parser to allow us access the cookies stored in the browser.
app.use(cookieParser());
// Configure middleware
// Use morgan logger for logging requests
app.use(logger("dev"));
// Parse request body as JSON
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
// Serve up static assets (usually on heroku)
if (process.env.NODE_ENV === "production") {
app.use(express.static("client/build"));
}
// // Make public a static folder
// app.use(express.static("public"));
// initialize express-session to allow us track the logged-in user across sessions.
app.use(
session({
key: "user_sid",
secret: "somerandomstuffs",
resave: false,
saveUninitialized: false,
cookie: {
expires: 600000,
},
})
);
// This middleware will check if user's cookie is still saved in browser and user is not set, then automatically log the user out.
// This usually happens when you stop your express server after login, your cookie still remains saved in the browser.
app.use((req, res, next) => {
if (req.cookies.user_sid && !req.session.user) {
res.clearCookie("user_sid");
}
next();
});
app.get('/api/home2', function(req, res) {
res.send('Welcome!');
});
app.get('/api/secret', withAuth, function(req, res) {
res.send('Hello ' + req.email);
});
// a simple route that will return a 200 HTTP status if our requester has a valid token:
app.get('/checkToken', withAuth, function(req, res) {
res.sendStatus(200);
})
// POST route to register a user
app.post('/api/register', function(req, res) {
const { email, password } = req.body;
const user = new User({ email, password });
user.save(function(err) {
if (err) {
res.status(500)
.send("Error registering new user please try again.");
} else {
res.status(200).send("Welcome to the club!");
}
});
});
//authenticate checker
app.post('/api/authenticate', function(req, res) {
const { email, password } = req.body;
User.findOne({ email }, function(err, user) {
if (err) {
console.error(err);
res.status(500)
.json({
error: 'Internal error please try again'
});
} else if (!user) {
res.status(401)
.json({
error: 'Incorrect email or password'
});
} else {
user.isCorrectPassword(password, function(err, same) {
if (err) {
res.status(500)
.json({
error: 'Internal error please try again'
});
} else if (!same) {
res.status(401)
.json({
error: 'Incorrect email or password'
});
} else {
// Issue token
const payload = { email };
const token = jwt.sign(payload, secret, {
expiresIn: '1h'
});
res.cookie('token', token, { httpOnly: true })
.sendStatus(200);
}
});
}
});
});
//logout user
app.get('/api/logout',withAuth,function(req,res){
res.clearCookie()
req.session.destroy();
res.sendStatus(200);
});
// adding the middleware to our express setup so express can parse cookies passed by our browser
app.use(cookieParser());
app.use(routes);
mongoose.connect(process.env.MONGODB_URI || "mongodb://localhost/populatedb");
// Start the server
app.listen(PORT, function () {
console.log(`???? ==> API Server now listening on PORT ${PORT}!`);
});
middleware.js
const jwt = require('jsonwebtoken');
const secret = 'mysecretsshhh';
const withAuth = function(req, res, next) {
const token = req.cookies.token;
if (!token) {
res.status(401).send('Unauthorized: No token provided');
} else {
jwt.verify(token, secret, function(err, decoded) {
if (err) {
res.status(401).send('Unauthorized: Invalid token');
} else {
req.email = decoded.email;
console.log("Hi " + req.email )
next();
}
});
}
}
module.exports = withAuth;
User.js(模型)
const mongoose = require("mongoose");
const bcrypt = require('bcrypt')
var Schema = mongoose.Schema;
var UserSchema = new Schema({
email: {
type: String,
unique: true,
required: true
},
// username: {
// type: String,
// unique: true,
// required: true
// },
password: {
type: String,
required: true
// trim: true,
// required: "Password is Required",
// validate: [
// function(input) {
// return input.length >= 6;
// },
// "Password should be longer."
// ]
},
});
UserSchema.pre("save", function (next) {
// Check if document is new or a new password has been set
if (!this.isModified("password")) {
// Saving reference to this because of changing scopes
return next()
}
this.password = bcrypt.hashSync(this.password, 10)
next()
})
//compare password
// UserSchema.methods.comparePassword = function (plainText, callback) {
// return callback(null, bcrypt.compareSync(plainText, this.password))
// }
UserSchema.methods.isCorrectPassword = function(password, callback){
bcrypt.compare(password, this.password, function(err, same) {
if (err) {
callback(err);
} else {
callback(err, same);
}
});
}
const userModel = mongoose.model("user", UserSchema)
var User = mongoose.model("User", UserSchema);
module.exports = User;
module.exports = userModel
【问题讨论】:
标签: node.js reactjs mongodb express authentication