Node.js 在post路由上的单个中间件功能中使用刷新令牌刷新JWT访问令牌

Node.js 在post路由上的单个中间件功能中使用刷新令牌刷新JWT访问令牌,node.js,express,authentication,jwt,middleware,Node.js,Express,Authentication,Jwt,Middleware,我正在努力学习express中的JWT身份验证,还有一件事我遇到了 这家伙已经初始化了一个中间件函数来验证和检查访问令牌的到期时间,如下所示: app.post("/protected", auth, (req, res) => { return res.json({ message: "Protected content!" }); }) 以及在刷新令牌 app.post("/refresh", (req, res,

我正在努力学习
express
中的
JWT
身份验证,还有一件事我遇到了

这家伙已经初始化了一个
中间件
函数来验证和检查访问令牌的到期时间,如下所示:

app.post("/protected", auth, (req, res) => {
    return res.json({ message: "Protected content!" });
})
以及在
刷新令牌

app.post("/refresh", (req, res, next) => {
    const refreshToken = req.body.token;
    if (!refreshToken || !refreshTokens.includes(refreshToken)) {
        return res.json({ message: "Refresh token not found, login again" });
    }

    // If the refresh token is valid, create a new accessToken and return it.
    jwt.verify(refreshToken, "refresh", (err, user) => {
        if (!err) {
            const accessToken = jwt.sign({ username: user.name }, "access", {
                expiresIn: "20s"
            });
            return res.json({ success: true, accessToken });
        } else {
            return res.json({
                success: false,
                message: "Invalid refresh token"
            });
        }
    });
});
所以,我的问题是它有多安全,我如何创建一个中间件功能,既可以进行身份验证,又可以刷新访问令牌,而不必点击
app.post('/refresh')
,因为在我看来,在react中的前端API管理中处理它并不是一个顺利的体验

编辑

我的中间件似乎工作得很好,但它没有识别出错误的刷新令牌,然后实际在受保护的路由上工作

app.post('/home', authenticateUser, (req, res) => {
    res.send('welcome');
});

async function authenticateUser(req, res, next) {
    let token = req.headers['authorization'];
    token = token.split(' ')[1];

    jwt.verify(token, JWT_AUTH_TOKEN, async (err, phone) => {
        if (phone) {
            req.phone = phone;
            next();
        } else if (err) {
            const refreshToken = req.body.refreshToken;
            if (!refreshToken || !refreshTokens.includes(refreshToken)) {
                return res.json({ message: 'Refresh token not found, login again' });
            } else {
                jwt.verify(refreshToken, JWT_REFRESH_TOKEN, (err, phone) => {
                    if (!err) {
                        const accessToken = jwt.sign({ phone }, JWT_AUTH_TOKEN, { expiresIn: '30s' });
                        return res.json({ success: true, accessToken });
                        
                    } else {
                        return res.json({
                            success: false,
                            message: 'Invalid refresh token'
                        });
                    }
                    next();
                });
            }
        } else {
            console.log(err);
            return res.status(403).json({ err, message: 'User not authenticated' });
        }
    });
}

他们/他只是避免每次发送刷新令牌,所以在失败后必须点击
/refresh
。如果您不介意每次在标头等中发送刷新令牌,那么您确实可以使用一个中间件,在获得
If(err.name==“tokenexpiredererror”)后,在验证刷新是否正常后刷新令牌{
etc各自拥有,但如果不是通过HTTPS,所有JWT都是不安全的。那么是否发送两个令牌取决于you@LawrenceCherone你能告诉我这是什么意思吗:
if(err.name=='TokenExpiredError'){
而且我也更新了自己的中间件功能。有什么建议我应该在哪里进行更改吗?它不会返回到私有路由,也不会标识代码中的无效刷新令牌。您应该仅在其
令牌过期错误
的情况下发布新令牌,可能还有其他原因它可能无法验证(),如篡改或无效等。我无法从您的代码中看出您将在何处发布
req.body.refreshToken
?这不会在每个路由上定义。因此,您应该将其作为标头发送回去,以便客户端可以在不影响当前有效负载的情况下提取新的令牌。所有操作都应该在标头中完成吗
app.post('/home', authenticateUser, (req, res) => {
    res.send('welcome');
});

async function authenticateUser(req, res, next) {
    let token = req.headers['authorization'];
    token = token.split(' ')[1];

    jwt.verify(token, JWT_AUTH_TOKEN, async (err, phone) => {
        if (phone) {
            req.phone = phone;
            next();
        } else if (err) {
            const refreshToken = req.body.refreshToken;
            if (!refreshToken || !refreshTokens.includes(refreshToken)) {
                return res.json({ message: 'Refresh token not found, login again' });
            } else {
                jwt.verify(refreshToken, JWT_REFRESH_TOKEN, (err, phone) => {
                    if (!err) {
                        const accessToken = jwt.sign({ phone }, JWT_AUTH_TOKEN, { expiresIn: '30s' });
                        return res.json({ success: true, accessToken });
                        
                    } else {
                        return res.json({
                            success: false,
                            message: 'Invalid refresh token'
                        });
                    }
                    next();
                });
            }
        } else {
            console.log(err);
            return res.status(403).json({ err, message: 'User not authenticated' });
        }
    });
}