签署 jwt 时,只保留 user_id 还是整个用户对象在有效载荷中更好?
Is it better to keep just the user_id or the whole user object in the payload when signing a jwt?
我知道有两种方法。
1) 传递整个用户对象:
let payload = {
user: {
id: user._id,
name:user.name,
email:user.email,
username:user.username
},
}
let token = jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: '1d' })
2) 仅传递 _id:
let token = jwt.sign({ id: this._id }, process.env.JWT_SECRET, {
expiresIn: '1d',
});
在第二种方法中,每当我想访问受保护的路由时,我都必须使用存储在有效负载中的 _id 调用数据库来获取用户的详细信息。
// protect.js
// Verify token
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = await User.findById(decoded.id);
虽然在第一种方法中,我总是有一个完整的用户详细信息对象,而无需进行额外的数据库调用。
在阅读了一些博客之后,我开始知道我们应该保持我们的负载轻量级,但我心中的问题是,另一方面,我们必须在每次访问受保护的路由时进行单独的数据库调用.
我想知道哪种方法更有效。
提前感谢您的回答:)
使用 ID 签署 JWT 令牌,因为它在初始创建后不太可能更改。
用户名和电子邮件等其他数据很容易发生变化。
编辑:这是我不久前做的一个练习中的用户注册示例。希望对大家有所帮助。
// POST api/users => Register user
router.post("/", (req, res) => {
const { name, email, password } = req.body;
// Simple validation
if (!name || !email || !password) {
return res.status(400).json({ msg: "Please enter required information" });
}
// Check for existing user
User.findOne({ email }).then((user) => {
if (user) return res.status(400).json({ msg: "User already exists" });
const newUser = new User({
name,
email,
password,
});
// Create salt and Hash
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(newUser.password, salt, (err, hash) => {
if (err) throw err;
newUser.password = hash;
newUser.save().then((user) => {
jwt.sign(
{ id: user.id },
jwtSecret,
{ expiresIn: 3600 },
(err, token) => {
if (err) throw err;
res.json({
token,
user: {
id: user.id,
name: user.name,
email: user.email,
},
});
}
);
});
});
});
});
});
假设您有一个包含整个用户对象的负载,包括:
- _id
- 名字
- 电子邮件
- 用户名
缺点案例:
假设用户后来修改了自己的名字,就意味着他的数据
在数据库中得到更新,但他的有效载荷仍然过时
旧名称,因为没有调用数据库来获取更新的记录。
如果用户现在尝试发出 POST 需要他的名字的请求
请求正文,然后过时的名称将被推送到
数据库而不是他的新名字。
app.post('/event', auth, (req, res) => {
// creates an event with his old name.
// Because the current payload contains old name.
})
现在如果用户注销然后再次登录,令牌将
在负载中包含用户的新名称。
并且每当使用用户的新更新名称获取所有事件时
保存在有效负载中,最近创建的最新事件
不会获取旧名称,因为它包含旧名称
用户名。
据我所知,这是我能给出的最好的解释。
分享您的想法!
谢谢
我知道有两种方法。
1) 传递整个用户对象:
let payload = {
user: {
id: user._id,
name:user.name,
email:user.email,
username:user.username
},
}
let token = jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: '1d' })
2) 仅传递 _id:
let token = jwt.sign({ id: this._id }, process.env.JWT_SECRET, {
expiresIn: '1d',
});
在第二种方法中,每当我想访问受保护的路由时,我都必须使用存储在有效负载中的 _id 调用数据库来获取用户的详细信息。
// protect.js
// Verify token
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = await User.findById(decoded.id);
虽然在第一种方法中,我总是有一个完整的用户详细信息对象,而无需进行额外的数据库调用。
在阅读了一些博客之后,我开始知道我们应该保持我们的负载轻量级,但我心中的问题是,另一方面,我们必须在每次访问受保护的路由时进行单独的数据库调用. 我想知道哪种方法更有效。
提前感谢您的回答:)
使用 ID 签署 JWT 令牌,因为它在初始创建后不太可能更改。
用户名和电子邮件等其他数据很容易发生变化。
编辑:这是我不久前做的一个练习中的用户注册示例。希望对大家有所帮助。
// POST api/users => Register user
router.post("/", (req, res) => {
const { name, email, password } = req.body;
// Simple validation
if (!name || !email || !password) {
return res.status(400).json({ msg: "Please enter required information" });
}
// Check for existing user
User.findOne({ email }).then((user) => {
if (user) return res.status(400).json({ msg: "User already exists" });
const newUser = new User({
name,
email,
password,
});
// Create salt and Hash
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(newUser.password, salt, (err, hash) => {
if (err) throw err;
newUser.password = hash;
newUser.save().then((user) => {
jwt.sign(
{ id: user.id },
jwtSecret,
{ expiresIn: 3600 },
(err, token) => {
if (err) throw err;
res.json({
token,
user: {
id: user.id,
name: user.name,
email: user.email,
},
});
}
);
});
});
});
});
});
假设您有一个包含整个用户对象的负载,包括:
- _id
- 名字
- 电子邮件
- 用户名
缺点案例:
假设用户后来修改了自己的名字,就意味着他的数据 在数据库中得到更新,但他的有效载荷仍然过时 旧名称,因为没有调用数据库来获取更新的记录。
如果用户现在尝试发出 POST 需要他的名字的请求 请求正文,然后过时的名称将被推送到 数据库而不是他的新名字。
app.post('/event', auth, (req, res) => { // creates an event with his old name. // Because the current payload contains old name. })
现在如果用户注销然后再次登录,令牌将 在负载中包含用户的新名称。
并且每当使用用户的新更新名称获取所有事件时 保存在有效负载中,最近创建的最新事件 不会获取旧名称,因为它包含旧名称 用户名。
据我所知,这是我能给出的最好的解释。 分享您的想法!
谢谢