2

我在 Node.js + Express 中有一个服务器,它向公众和管理员公开了一些 API。实际上我有 2 个正在运行的克隆实例,一个用于测试,一个用于生产。它们是双胞胎,公开相同的路由(/admin, /public),但连接到两个不同的数据库,并部署在两个不同的地址上。

我想使用 Express-Gateway 向 3d 方提供 API,所以我将首先让他们访问测试服务器。全部完成后,我还将为他们提供生产访问权限。

为此,我的想法是只创建 1eg user和多个eg application. 每个eg application人都eg credentials必须访问服务器或生产。

                                             http://server_test.com
            |-------------|                    |-------------|
            |   App Prod  |                    | Server Test |
    +----►  |    scopes:  |------+     +-----► |    /public  |
    |       | [api_prod]  |      |     |       |    /admin   |
    |       |-------------|      ▼     |       |-------------|
    |                       http://gateway.com
|------|                     |------------|         
| User |                     |   Express  |  
|------|                     |   Gateway  |    
    |       |-------------|  |------------|                     
    |       |   App Test  |      ▲     |    http://server_prod.com
    +----►  |    scopes:  |      |     |       |-------------|             
            | [api_test]  |------+     +-----► | Server Prod |     
            |-------------|                    |    /public  |                 
                                               |    /admin   |                   
                                               |-------------|

根据提供的凭据,网关应将请求重定向到server_test.comserver_prod.com。我的想法是用来eg scopes处理对正确端点的请求。因此,服务器测试策略将需要范围api_test,而服务器产品将需要api_prod范围。

无论如何,这个解决方案不起作用,因为如果第一个匹配apiEndpoints失败,它只会导致“未找到”。

示例:我请求使用带范围的http://gateway.com/publicApp Prod 凭据。api_prod它应该被传递给http://server_prod.com/public,但它匹配第一个paths: '/*'testEndpoint并且不符合范围条件。所以它只是失败了,而正确的 apiEndpoint 应该是prodEndpoint.

我怎么解决这个问题?

这是我的 gateway.config.yml

apiEndpoints:
   testEndpoint
      host:*
      paths: '/*'            # <--- match this
      scopes: ["api_test"]   # <--- but fails this
   prodEndpoint
      host:*
      paths: '/*'
      scopes: ["api_prod"]   # <---- this is right
serviceEndpoints
    testService      
      url: "http://server_test.com"
    prodService      
      url: "http://server_prod.com"
policies
    - proxy
pipelines
    testEndpoint:              # Test
       apiEndpoints:
         - testEndpoint
       policies:
         - proxy
           - action
             serviceEndpoint: testService
    prodEndpoint:              # Prod
       apiEndpoints:
         - prodEndpoint
       policies:
         - proxy
           - action
             serviceEndpoint: prodService
4

1 回答 1

1

我以这种方式解决了:使用-rewrite策略。

  • 我在客户的请求前加上/test/prod
  • 使用前缀匹配path正确的 apiEndpoint
  • 重写请求,删除前缀
  • 选择 serviceEndpoint 并继续...
                                        http://server_test.com
|-------------|                              |-------------|
|   App Prod  | /prod/admin          /admin  | Server Test |
|    scopes:  |-------------+     +--------► |    /public  |
| [api_prod]  |             |     |          |    /admin   |
|-------------|             ▼     |          |-------------|
                        http://gateway.com
                         |------------|         
                         |   Express  |  
                         |   Gateway  |    
|-------------|          |------------|                     
|   App Test  |             ▲     |        http://server_prod.com
|    scopes:  |             |     |           |-------------|             
| [api_test]  |-------------+     +---------► | Server Prod |     
|-------------| /test/admin          /admin   |    /public  |                 
                                              |    /admin   |                   
                                              |-------------|

这是我的配置文件:

apiEndpoints:
   testEndpoint
      host:*
      paths: '/test/*'        
      scopes: ["api_test"]   
   prodEndpoint
      host:*
      paths: '/prod/*'
      scopes: ["api_prod"]  
serviceEndpoints
    testService      
      url: "http://server_test.com"
    prodService      
      url: "http://server_prod.com"
policies
    - proxy
pipelines
    testEndpoint:              # Test
       apiEndpoints:
         - testEndpoint
       policies:
         - rewrite:            # rewrite - delete /test
           -
             condition:
                name: regexpmatch
                match: ^/test/?(.*)$
             action:
               rewrite: /$1   
         - proxy
           - action
             serviceEndpoint: testService
    prodEndpoint:              # Prod
       apiEndpoints:
         - prodEndpoint
       policies:
         - rewrite:           # rewrite - delete /prod
           -
             condition:
                name: regexpmatch
                match: ^/prod/?(.*)$
             action:
               rewrite: /$1  
         - proxy
           - action
             serviceEndpoint: prodService
于 2020-01-30T13:47:20.673 回答