You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用await时出现无限等待,Refresh Token异步函数无返回结果求助

问题:Refresh Token异步函数无限运行无返回结果

我在实现Refresh Token功能时,异步函数loginUserTkRefresh无限运行且没有任何结果返回,多次检查语法、合并文件都无法解决。相关代码如下:

相关代码文件

users.js

const jwt = require("jsonwebtoken");

module.exports = {
    loginUserTkRefresh: async (req, res) => {
        const refreshToken = req.body.token
        
        if(!refreshToken) return res.status(401);
        
        try {
            await jwt.verify(refreshToken, process.env.REFRESH_ACCESS_TOKEN);
        } catch (err) {
            return res.sendStatus(403);
        }

        const accessToken = jwt.sign(
            { id: 1 },
            process.env.ACCESS_TOKEN,
            { expiresIn: 200 }
        );
        res.send({ accessToken });
    },
};

api.js

const express = require("express");
const jwt = require("jsonwebtoken");
const router = express.Router();
const user = require("../actions/api/users");

router.get("/users", authenticate, (req, res) => {
    const users = [{ id: 1, email: "adam@op.pl", password: "12321" }];
    res.send(users);
});

router.post("/auth/login", user.loginUser);
router.post("/auth/refresh", user.loginUserTkRefresh);

function authenticate(req, res, next) {
    const authHeader = req.headers["authorization"];
    const token = authHeader && authHeader.split(" ")[1];

    if (token === null) return res.status(401);

    jwt.verify(token, process.env.ACCESS_TOKEN, (err, user) => {
        if (err) return res.sendStatus(403);
        req.user = user;
        next();
    });
}

module.exports = router;

index.js

const express = require("express");
require("dotenv").config();

const app = express();

const { port } = require("./config/config");
const apiRouter = require("./routes/api");

app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// routes
app.use("/api", apiRouter);

// server
app.listen(port, () => {
    console.log("Server is listening...");
    console.log(`\tAddress: http://localhost:${port}`);
});

请求示例

POST http://localhost:3000/api/auth/refresh
Content-Type: "application/json"

{
    "token":" "
}

解决方案

问题核心:原生jsonwebtoken库的jwt.verify默认是回调式API,并非Promise对象,直接用await调用会导致代码一直处于pending状态,异步函数无法继续执行,最终表现为无限运行无返回。

提供两种修复方式:

方式1:用util.promisify包装为Promise版本

const jwt = require("jsonwebtoken");
const { promisify } = require("util");
// 将jwt.verify转换为支持await的Promise函数
const verifyToken = promisify(jwt.verify);

module.exports = {
    loginUserTkRefresh: async (req, res) => {
        const refreshToken = req.body.token
        
        if(!refreshToken) return res.status(401);
        
        try {
            // 使用包装后的函数执行验证
            await verifyToken(refreshToken, process.env.REFRESH_ACCESS_TOKEN);
        } catch (err) {
            return res.sendStatus(403);
        }

        const accessToken = jwt.sign(
            { id: 1 },
            process.env.ACCESS_TOKEN,
            { expiresIn: 200 }
        );
        res.send({ accessToken });
    },
};

方式2:改用回调式逻辑处理

如果不想使用Promise,直接采用jwt.verify原生回调写法,移除async/await:

const jwt = require("jsonwebtoken");

module.exports = {
    loginUserTkRefresh: (req, res) => {
        const refreshToken = req.body.token
        
        if(!refreshToken) return res.status(401);
        
        jwt.verify(refreshToken, process.env.REFRESH_ACCESS_TOKEN, (err) => {
            if (err) return res.sendStatus(403);
            
            const accessToken = jwt.sign(
                { id: 1 },
                process.env.ACCESS_TOKEN,
                { expiresIn: 200 }
            );
            res.send({ accessToken });
        });
    },
};

额外注意:测试时请传入有效的Refresh Token,请求示例中的空格字符串会直接触发403返回。

内容的提问来源于stack exchange,提问作者Szubierski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 04:18:24