为什么在同一文件中的其他实例中,为.save()的特定实例抛出版本错误?

发布于 2025-02-13 12:50:51 字数 2818 浏览 1 评论 0原文

我更新了一些控制器文件以实现刷新令牌旋转,其中包括我的RefreshTokenController文件,该文件用于返回带有有效刷新令牌cookie的API调用时返回新的访问令牌。但是,从那以后,它在接收API调用时会丢弃版本错误,但是我无法弄清楚为什么该错误是从第61行中的第三个实例出现的(即,仅当我时,该错误才会消失评论.save()的第三个实例,但是当我在第32和49行上的前两个实例中评论了前两个实例中的两个实例。任何见解都将不胜感激。谢谢。

1    const jwt = require('jsonwebtoken');
2    const { defineModel } = require('../services/dbHandler');
3    const { userSchema } = require('../schemas/userSchema');
4    const { authTokenErr, cookieOptions, serverErr } = require('../utils');
5
6    const refreshAccessToken = async (req, res) => {
7      const prevRefreshToken = req.cookies?.refToken;
8
9      if (!prevRefreshToken) return res.status(401).json(authTokenErr);
10
11     res.clearCookie('refToken', prevRefreshToken, cookieOptions);
12
13     try {
14       const User = await defineModel('global', 'User', userSchema);
15
16       const dbUserWithToken = await User.findOne({
17         refreshToken: prevRefreshToken,
18       }).exec();
19
20       if (!dbUserWithToken) {
21         jwt.verify(
22           prevRefreshToken,
23           process.env.REFRESH_TOKEN_SECRET,
24           async (err, payload) => {
25             if (err) return res.status(401).json(authTokenErr);
26
27             const compromisedDbUser = await User.findOne({
28               _id: payload._uid,
29             }).exec();
30
31             compromisedDbUser.refreshToken = [];
32             await compromisedDbUser.save();
33           }
34         );
35
36         return res.status(401).json(authTokenErr);
37       }
38
39       const updatedTokenArr = dbUserWithToken.refreshToken.filter(
40         (token) => token !== prevRefreshToken
41       );
42
43       jwt.verify(
44         prevRefreshToken,
45         process.env.REFRESH_TOKEN_SECRET,
46         async (err, payload) => {
47           if (err || payload._uid !== dbUserWithToken._id.toString()) {
48             dbUserWithToken.refreshToken = [...updatedTokenArr];
49             const result = await dbUserWithToken.save();
50
51             return res.status(401).json(authTokenErr);
52           }
53
54           const renewedRefreshToken = dbUserWithToken.generateRefreshToken();
55           const renewedAccessToken = dbUserWithToken.generateAccessToken();
56
57           dbUserWithToken.refreshToken = [
58             ...updatedTokenArr,
59             renewedRefreshToken,
60           ];
61           await dbUserWithToken.save();    // <---- Cause of Version Error
62
63           res.cookie('refToken', renewedRefreshToken, cookieOptions);
64
65           return res.status(200).json({ accessToken: renewedAccessToken });
66         }
67       );
68     } catch (err) {
69       res.status(500).json(serverErr);
70       console.error(err);
71     }
72   };
73
74   module.exports = { refreshAccessToken };

I updated some of my Controller files to implement refresh token rotation, and that included my refreshTokenController file, which used to return a new access token on receiving an api call with a valid refresh token cookie. However, since then, it's throwing a Version Error on receiving the api call, but I can't figure out why the error is specifically coming from the third instance of .save() on line 61 (i.e., the error disappears only when I comment out the third instance of .save(), but not when I comment out either or both of the previous two instances of .save() on lines 32 and 49). Any insight would be appreciated. Thanks.

1    const jwt = require('jsonwebtoken');
2    const { defineModel } = require('../services/dbHandler');
3    const { userSchema } = require('../schemas/userSchema');
4    const { authTokenErr, cookieOptions, serverErr } = require('../utils');
5
6    const refreshAccessToken = async (req, res) => {
7      const prevRefreshToken = req.cookies?.refToken;
8
9      if (!prevRefreshToken) return res.status(401).json(authTokenErr);
10
11     res.clearCookie('refToken', prevRefreshToken, cookieOptions);
12
13     try {
14       const User = await defineModel('global', 'User', userSchema);
15
16       const dbUserWithToken = await User.findOne({
17         refreshToken: prevRefreshToken,
18       }).exec();
19
20       if (!dbUserWithToken) {
21         jwt.verify(
22           prevRefreshToken,
23           process.env.REFRESH_TOKEN_SECRET,
24           async (err, payload) => {
25             if (err) return res.status(401).json(authTokenErr);
26
27             const compromisedDbUser = await User.findOne({
28               _id: payload._uid,
29             }).exec();
30
31             compromisedDbUser.refreshToken = [];
32             await compromisedDbUser.save();
33           }
34         );
35
36         return res.status(401).json(authTokenErr);
37       }
38
39       const updatedTokenArr = dbUserWithToken.refreshToken.filter(
40         (token) => token !== prevRefreshToken
41       );
42
43       jwt.verify(
44         prevRefreshToken,
45         process.env.REFRESH_TOKEN_SECRET,
46         async (err, payload) => {
47           if (err || payload._uid !== dbUserWithToken._id.toString()) {
48             dbUserWithToken.refreshToken = [...updatedTokenArr];
49             const result = await dbUserWithToken.save();
50
51             return res.status(401).json(authTokenErr);
52           }
53
54           const renewedRefreshToken = dbUserWithToken.generateRefreshToken();
55           const renewedAccessToken = dbUserWithToken.generateAccessToken();
56
57           dbUserWithToken.refreshToken = [
58             ...updatedTokenArr,
59             renewedRefreshToken,
60           ];
61           await dbUserWithToken.save();    // <---- Cause of Version Error
62
63           res.cookie('refToken', renewedRefreshToken, cookieOptions);
64
65           return res.status(200).json({ accessToken: renewedAccessToken });
66         }
67       );
68     } catch (err) {
69       res.status(500).json(serverErr);
70       console.error(err);
71     }
72   };
73
74   module.exports = { refreshAccessToken };

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

薄荷梦 2025-02-20 12:50:51

我还发现这仅在我的使用效率API提取中发生。看到我现在使用React 18时,我尝试禁用严格的模式,并且版本错误消失了。因此,最终,版本控制错误是由React 18在严格模式下对所有使用效果挂钩的新的双重渲染引起的(并且与我的3个document.save.save.save.save()在同一文件中无关)。现在,我只需要弄清楚为什么我的清理功能无法在我的usefetch钩上使用。

I also found that this was only occurring with my useEffect api fetches. Seeing as I'm now on react 18, I tried disabling strict mode, and the Version Error disappeared. So in the end, the versioning error was caused by react 18's new double-rendering of all useEffect hooks in strict mode (and had nothing to do with my 3 instances of document.save() in the same file after all). Now I just have to figure out why my clean-up function is not working on my useFetch hook.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文