【问题标题】:Passport Authentication Middleware for Node/Express - How to Protect all RoutesNode/Express 的 Passport 身份验证中间件 - 如何保护所有路由
【发布时间】:2021-12-06 23:41:34
【问题描述】:

堆栈:

前端 - Angular 12

|-- 利用 Angular/MSAL 与 Azure AD 集成 身份验证

后端:

|-- 节点JS V14.17.6
|-- Express 4.17.1
|-- 护照-Azure-AD V4.3.0(passport-azure-ad 是 Passport Strategies 的集合 帮助

您与 Azure Active 集成 |-- 身份验证策略 - BearerStrategy(保护 API 和资源) 目录) |-- Passport V0.3.2(Passport-Azure-AD 使用的 Passport 版本)

后端项目结构(为简洁起见摘录) 根目录 |-- 源 |-- 路由器(在单个 .js 文件中保存每个实体的所有模块化路由的子目录,例如 users.js、actions.js) |--index.js(应用入口点)

我正在寻找一种方法来保护我的所有路由/api端点,而不是必须将passport.authenticate应用于每个路由端点内的每个路由处理程序,这可能是每个模块化路由的“N”个路由.js 文件,如上所述。我尝试了以下方法无济于事。

  1. 在 index.js 文件中,即我使用的应用程序入口点,例如const users = require('./routers/users') 和 app.use('/api/v1/users', users) 来挂载我的路由处理程序,我介绍了以下 app.use(passport.authenticate('oauth- Bearer', { session: false })) 因为护照是一个中间件但没有乐趣

  2. 在模块化路由处理文件中,我也尝试了以下方法: router.all('*',passport.authenticate('oauth-bearer', { session: false })) 基于快速文档 router.所有人都应该在所有请求方法的路径上应用中间件或提供的函数/处理程序,在这种情况下,'*' 应该匹配所有路径,但这仍然只适用于基本路径“/”而不适用于文件中的其他路径,例如'/关系'

如果有人能开出保护所有路线的方法,将不胜感激。

【问题讨论】:

    标签: node.js angular azure express


    【解决方案1】:
    1. router.all() 函数与 router.METHOD() 方法类似,只是它匹配所有 HTTP 方法(动词)。

    如果我写,router.all('/users', callback),这意味着回调将为端点/users 的每个方法(GET、POST、DELETE、PATCH、PUT 等)运行。

    如果想为每条路线运行它,你需要做这样的事情 -

    router.all('*', callback)

    1. 我喜欢使用router.use() 函数,该函数专门针对此类用例。假设我的监控路由中有 2 个端点。如果我想为两者都设置身份验证保护,我喜欢这样做 -
    const constant = require(__basePath + 'app/config/constant');
    const router   = require('express').Router({
        caseSensitive: true,
        strict       : true
    });
    const monitor  = require(constant.path.module + 'monitor/monitor.controller');
    const Passport      = require('passport');
    const AuthGuard     = Passport.authenticate(['user', 'admin'], { session : false });
    
    router.use(AuthGuard);
    
    router.get(
        '/ping',
        monitor.ping
    );
    
    router.get(
        '/status',
        monitor.status
    );
    
    module.exports = {
        router: router
    };
    

    附: - 请忽略constantpath相关的东西,仅供参考。

    【讨论】:

    • 您好 Pankaj,感谢您抽出宝贵时间回答我的问题。因此,谈到 Router 实例的“all”方法,我确实熟悉它的功能。我想指出您对 passport.authenticate 的使用,不确定这是错误还是无意的遗漏;注意到您没有提供所需的第一个参数,即护照策略,因此在我的情况下,这将是一个承载策略,因为我严格需要保护资源/api 端点。如果没有提供的策略,您的上述实现将导致错误
    • 嗨@nubianMONK,我使用的这两个策略(['user', 'admin'],,是在一个单独的护照服务文件中定义的(在主服务器文件中导入和初始化)。我只是想解释一下我如何使用router.use()
    【解决方案2】:

    所以在寻找解决方案多天后,我终于找到了为什么我的上述实施不起作用的罪魁祸首。它归结为最近引入的通配符'*' 功能,因为它适用于 MSAL/Angular 的 protectedResourceMap。利用上面的示例,从客户端(Angular V12)实现的方式是将上述受保护的资源映射设置为:'http://localhost:3001/api/v1/*',这在逻辑上会很好转保护端点,例如

    1. 'http://localhost:3001/api/v1/users'
    2. 'http://localhost:3001/api/v1/users/relationshp'

    但我发现通配符并不像人们想象的那样工作,它几乎只会匹配上面标记为 (1.) 的第一个 url,因为这是在“users.js”路由器文件中处理的路由器处理程序,基本端点 router.get('/', (req, res, next) => {...do something });并将完全抛弃以下路由器处理程序(应匹配上面标记为 (2.) 的第二个 url),端点 router.get('/relationships', (req, res, next) => {...do something });顺便说一句,它同样在“users.js”路由器文件中实现。

    节省一天客户端修复(Angular V12)的解决方案是首先删除通配符 asterix '*' 作为受保护资源映射配置的一部分,并保持原样:'http://localhost:3001/api /v1/' 并根据我的要求在服务器端(NodeJs),即保护所有路由是将以下解决方案应用于服务器解决方案“index.js”的入口点,利用护照作为全面应用于应用程序的中间件: app.use(passport.authenticate('oauth-bearer', { session: false }));这种方式不需要在每个路由器处理程序文件中实现相同的。希望这对面临类似问题的人们有所帮助。

    【讨论】:

      猜你喜欢
      • 2020-05-10
      • 2019-10-28
      • 2021-12-16
      • 2020-02-06
      • 2018-09-21
      • 2013-05-28
      • 2021-11-07
      • 2013-03-27
      • 2014-11-19
      相关资源
      最近更新 更多