通过电子邮件重置密码
Resetting password via email
抱歉这么久 post,我正在尝试通过电子邮件重置密码,直到现在我设法将重置 link 发送到电子邮件,现在我在后台尝试了这个:
userRouter.get('/reset', expressAsyncHandler(async (req, res) => {
const user = await User.findOne({
where: {
resetPasswordToken: req.query.resetPasswordToken,
resetPasswordExpires: {
$gt: Date.now(),
},
},
});
if (user) {
console.log('token matched')
res.status(200).send({
message: 'password reset link ok'
})
} else {
console.log('password reset link is invalid or has expired');
res.json('password reset link is invalid or has expired');
}
})
);
在忘记密码时,我做了类似这样的事情来更新两个字段:
user.update({
resetPasswordToken: token,
resetPasswordExpires: Date.now() + 360000,
});
我的用户模型是:
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
isAdmin: { type: Boolean, default: false, required: true }
当我尝试使用 where 子句检查 resetPasswordToken 是否返回我的所有用户时,这是错误的。我在想我需要在模型中声明 resetPasswordToken 和 resetPasswordExpires 以使其两项工作?还是足够了?另一个问题是,我必须将什么发送到前端才能正常工作?
在 react-redux 中,我有以下功能,但我 100% 发送了错误的数据:
export const checktoken = (email) => async (dispatch) => {
dispatch({ type: USER_RESET_PASSWORD_REQUEST, payload: { email } });
try {
const { data } = await Axios.get('/api/users/reset');
dispatch({ type: USER_RESET_PASSWORD_SUCCESS, payload: data });;
localStorage.setItem('userInfo', JSON.stringify(data));
} catch (error) {
dispatch({
type: USER_RESET_PASSWORD_FAIL,
payload:
error.response && error.response.data.message
? error.response.data.message
: error.message,
});
}
};
首先,您的模型没有 resetPasswordToken
和 resetPasswordExpires
字段。这意味着您的 update
将不起作用。我假设您使用的是 mongoose,并且 mongoose 不会更新模型中不存在的字段。
添加条目如下。
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
isAdmin: { type: Boolean, default: false, required: true },
resetPasswordToken: { type: String },
resetPasswordExpires: { type: Number }
其次,您的查询有误。查询应该像...
const user = await User.findOne({
resetPasswordToken: req.query.resetPasswordToken,
resetPasswordExpires: {
$gt: Date.now(),
},
});
注意:经常检查您的数据库,看看您的 update
条目是否确实更新了。
前端
验证用户 + 令牌存在后,您可以 res.status(200).send()
到您的网络应用程序。
在您的网络应用程序中,您将请求用户输入新密码。用户输入新密码后,您会将新密码 AND 令牌(再次)发送到后端。
这一次,您需要在将密码更新到用户模型之前再次验证令牌。这将确保重置密码来自有效来源。
您可能希望在更新密码后从文档中删除 resetPasswordToken 和 resetPasswordExpires,因为不再需要它。
抱歉这么久 post,我正在尝试通过电子邮件重置密码,直到现在我设法将重置 link 发送到电子邮件,现在我在后台尝试了这个:
userRouter.get('/reset', expressAsyncHandler(async (req, res) => {
const user = await User.findOne({
where: {
resetPasswordToken: req.query.resetPasswordToken,
resetPasswordExpires: {
$gt: Date.now(),
},
},
});
if (user) {
console.log('token matched')
res.status(200).send({
message: 'password reset link ok'
})
} else {
console.log('password reset link is invalid or has expired');
res.json('password reset link is invalid or has expired');
}
})
);
在忘记密码时,我做了类似这样的事情来更新两个字段:
user.update({
resetPasswordToken: token,
resetPasswordExpires: Date.now() + 360000,
});
我的用户模型是:
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
isAdmin: { type: Boolean, default: false, required: true }
当我尝试使用 where 子句检查 resetPasswordToken 是否返回我的所有用户时,这是错误的。我在想我需要在模型中声明 resetPasswordToken 和 resetPasswordExpires 以使其两项工作?还是足够了?另一个问题是,我必须将什么发送到前端才能正常工作?
在 react-redux 中,我有以下功能,但我 100% 发送了错误的数据:
export const checktoken = (email) => async (dispatch) => {
dispatch({ type: USER_RESET_PASSWORD_REQUEST, payload: { email } });
try {
const { data } = await Axios.get('/api/users/reset');
dispatch({ type: USER_RESET_PASSWORD_SUCCESS, payload: data });;
localStorage.setItem('userInfo', JSON.stringify(data));
} catch (error) {
dispatch({
type: USER_RESET_PASSWORD_FAIL,
payload:
error.response && error.response.data.message
? error.response.data.message
: error.message,
});
}
};
首先,您的模型没有 resetPasswordToken
和 resetPasswordExpires
字段。这意味着您的 update
将不起作用。我假设您使用的是 mongoose,并且 mongoose 不会更新模型中不存在的字段。
添加条目如下。
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
isAdmin: { type: Boolean, default: false, required: true },
resetPasswordToken: { type: String },
resetPasswordExpires: { type: Number }
其次,您的查询有误。查询应该像...
const user = await User.findOne({
resetPasswordToken: req.query.resetPasswordToken,
resetPasswordExpires: {
$gt: Date.now(),
},
});
注意:经常检查您的数据库,看看您的 update
条目是否确实更新了。
前端
验证用户 + 令牌存在后,您可以 res.status(200).send()
到您的网络应用程序。
在您的网络应用程序中,您将请求用户输入新密码。用户输入新密码后,您会将新密码 AND 令牌(再次)发送到后端。
这一次,您需要在将密码更新到用户模型之前再次验证令牌。这将确保重置密码来自有效来源。
您可能希望在更新密码后从文档中删除 resetPasswordToken 和 resetPasswordExpires,因为不再需要它。