【问题标题】:What is the best way to verify authentication token of different type of users?验证不同类型用户的身份验证令牌的最佳方法是什么?
【发布时间】:2021-04-26 01:19:03
【问题描述】:

假设我有 10 条路线,每条路线只有特定类型的用户可以访问。当用户登录时,会生成一个令牌。这些用户令牌是由他们的_id 和一个存储在.env 文件中的令牌秘密生成的。

通常每个用户类型的令牌验证是通过单独的函数完成的,因为不同类型的用户具有不同的令牌秘密。比如user1的token secret可能是TOKEN_SECRET_USER2 = 6ygfewf6hj,user2的token可能是TOKEN_SECRET_USER1 = 87uhjkaf89

当对路由发出任何请求时,会验证用户令牌以查看用户是否可以访问该路由。

以下是不同用户类型可访问的两个示例路由,

// Route accessible to user type 1
router.get("/foo", verifyTokenUSER1, async (req, res) => {
    // All the good stuff
});

// Route accessible to user type 2
router.post("/bar", verifyTokenUSER2, async (req, res) => {
    // All the good stuff
});

这是一些验证模块的方法,

// Verification for user 1
const verifyTokenUSER1 = (req, res, next) => {

    const token = req.header("auth-token");
    if (!token) return res.status(401).send();

    try {
        jwt.verify(token, process.env.TOKEN_SECRET_USER1);

        next();
    } catch (err) {
        res.status(401).send();
    }
};

// Verification for user 2
const verifyTokenUSER2 = (req, res, next) => {

    const token = req.header("auth-token");
    if (!token) return res.status(401).send();

    try {
        jwt.verify(token, process.env.TOKEN_SECRET_USER2);

        next();
    } catch (err) {
        res.status(401).send();
    }
};

如您所见,上述方法只有一个变化,即用户类型的访问令牌秘密。

如果可能,我想使用 1(one) 单个函数来验证它们。但是我不能将任何值作为参数传递给验证方法。那么,这里如何去除重复呢?

【问题讨论】:

    标签: node.js express jwt


    【解决方案1】:

    如果您使用bind (mdn),您实际上可以将参数传递给 verify 方法:

    // Route accessible to user type 1
    router.get("/foo", verifyToken.bind(null, process.env.TOKEN_SECRET_USER1), async (req, res) => {
        // All the good stuff
    });
    
    // Route accessible to user type 2
    router.post("/bar", verifyToken.bind(null, process.env.TOKEN_SECRET_USER2), async (req, res) => {
        // All the good stuff
    });
    

    这里函数的bind 方法接收2 个参数:第一个是函数的this 上下文,第二个是第一个参数。它返回一个新函数,该函数将接收提供的令牌作为第一个参数,并将接收req, res, next 作为下一个参数。

    const verifyToken = (tokenSecret, req, res, next) => {
    
        const token = req.header("auth-token");
        if (!token) return res.status(401).send();
    
        try {
            jwt.verify(token, tokenSecret);
    
            next();
        } catch (err) {
            res.status(401).send();
        }
    };
    

    另一种等效的方法是构建一个验证方法“工厂”,它返回一个在令牌上具有闭包 (mdn) 的验证函数:

    
    // Route accessible to user type 1
    router.get("/foo", getTokenVerifier(process.env.TOKEN_SECRET_USER1), async (req, res) => {
        // All the good stuff
    });
    
    // Route accessible to user type 2
    router.post("/bar", getTokenVerifier(process.env.TOKEN_SECRET_USER2), async (req, res) => {
        // All the good stuff
    });
    
    // this function returns a new function, with a closure on the provided tokenSecret
    const getTokenVerifier = (tokenSecret) => {
      return (req, res, next) => {
        const token = req.header("auth-token");
        if (!token) return res.status(401).send();
    
        try {
            jwt.verify(token, tokenSecret);
    
            next();
        } catch (err) {
            res.status(401).send();
        }
      }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-27
      • 1970-01-01
      • 2018-08-03
      • 2013-10-18
      • 1970-01-01
      • 2016-05-27
      相关资源
      最近更新 更多