我在Authentication in NodeJS With Express and Mongo - CodeLab #1上学习教程
我得到了一切完美的工作,但教程并没有解决如何注销用户。
据我所知,该会话正在保存在Mongoose Atlas上,这是我正在使用的数据库。当我用Postman登录用户时,我会得到一个令牌。但我不确定如何配置/logout路由。
下面是我的代码:
//routes/user.js
const express = require("express");
const { check, validationResult } = require("express-validator");
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
const router = express.Router();
const auth = require("../middleware/auth");
const User = require("../models/User");
/**
* @method - POST
* @param - /signup
* @description - User SignUp
*/
//Signup
router.post(
"/signup",
[
check("username", "Please Enter a Valid Username")
.not()
.isEmpty(),
check("email", "Please enter a valid email").isEmail(),
check("password", "Please enter a valid password").isLength({
min: 6
})
],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({
errors: errors.array()
});
}
const {
username,
email,
password
} = req.body;
try {
let user = await User.findOne({
email
});
if (user) {
return res.status(400).json({
msg: "User Already Exists"
});
}
user = new User({
username,
email,
password
});
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(password, salt);
await user.save();
const payload = {
user: {
id: user.id
}
};
jwt.sign(
payload,
"randomString", {
expiresIn: 10000
},
(err, token) => {
if (err) throw err;
res.status(200).json({
token
});
}
);
} catch (err) {
console.log(err.message);
res.status(500).send("Error in Saving");
}
}
);
// Login
router.post(
"/login",
[
check("email", "Please enter a valid email").isEmail(),
check("password", "Please enter a valid password").isLength({
min: 6
})
],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({
errors: errors.array()
});
}
const { email, password } = req.body;
try {
let user = await User.findOne({
email
});
if (!user)
return res.status(400).json({
message: "User Not Exist"
});
const isMatch = await bcrypt.compare(password, user.password);
if (!isMatch)
return res.status(400).json({
message: "Incorrect Password !"
});
const payload = {
user: {
id: user.id
}
};
jwt.sign(
payload,
"randomString",
{
expiresIn: 3600
},
(err, token) => {
if (err) throw err;
res.status(200).json({
token
});
}
);
} catch (e) {
console.error(e);
res.status(500).json({
message: "Server Error"
});
}
}
);
// router.route("/logout").get(function (req, res, next) {
// if (expire(req.headers)) {
// delete req.user;
// return res.status(200).json({
// "message": "User has been successfully logged out"
// });
// } else {
// return next(new UnauthorizedAccessError("401"));
// }
// });
router.get("/me", auth, async (req, res) => {
try {
// request.user is getting fetched from Middleware after token authentication
const user = await User.findById(req.user.id);
res.json(user);
} catch (e) {
res.send({ message: "Error in Fetching user" });
}
});
router.get('/logout', isAuthenticated, function (req, res) {
console.log('User Id', req.user._id);
User.findByIdAndRemove(req.user._id, function (err) {
if (err) res.send(err);
res.json({ message: 'User Deleted!' });
})
});
module.exports = router;
function isAuthenticated(req, res, next) {
console.log("req: " + JSON.stringify(req.headers.authorization));
// if (!(req.headers && req.headers.authorization)) {
// return res.status(400).send({ message: 'You did not provide a JSON web token in the authorization header' });
//}
};
///middleware/auth.js
const jwt = require("jsonwebtoken");
module.exports = function (req, res, next) {
const token = req.header("token");
if (!token) return res.status(401).json({ message: "Auth Error" });
try {
const decoded = jwt.verify(token, "randomString");
req.user = decoded.user;
next();
} catch (e) {
console.error(e);
res.status(500).send({ message: "Invalid Token" });
}
};
///models/User.js
const mongoose = require("mongoose");
const UserSchema = mongoose.Schema({
username: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
createdAt: {
type: Date,
default: Date.now()
}
});
// export model user with UserSchema
module.exports = mongoose.model("user", UserSchema);
因此,我的问题是,如何实现/logout路由,以便在用户单击logout按钮并调用该路由时,销毁他们的令牌。我只是问后端的部分。我可以使用axios。
- 谢谢-谢谢
3条答案
按热度按时间xdnvmnnf1#
从我所看到的,你没有保存任何会话数据或存储令牌的任何地方-这是伟大的。您只需将令牌附加到API请求中的标头。
因此,您唯一可以做的事情可能是使
/logout route
中的令牌过期,然后确保删除客户端上的令牌-可以是localStorage,sessionStorage等-您的客户端代码需要杀死令牌,以便它不能再次包含。旁注:
1.您不会在任何地方延长令牌的生命周期,因此即使用户继续在网站上进行交互,令牌的到期时间也不会更新。您将需要手动刷新令牌/生成新令牌以具有滑动到期时间。
1.我建议你把代币保存在饼干里。将cookie设置为HttpOnly、Secure并指定域。这是更安全,并允许您也从API过期的cookie。如果您包含的任何脚本遭到破坏,它们可以轻松访问所有用户的令牌。
示例如下:
字符串
然后在注销时:
型
6jjcrrmo2#
当你使用JWT时,后端总是会检查2件事1.正确的令牌2.如果时间到了(你应该处理这个)
对于第二点,如果用户时间超过前端,如果您已将令牌存储在本地存储中,则可以删除令牌。
对于注销,当用户单击注销时,只需从本地存储中删除JWT并重定向到登录或其他页面
gkn4icbw3#
这是一个简单的解决方案
字符串
}
注销用户的简单方法