Sinatra 如何使用 Rack::Protection::AuthenticityToken 除了某些 api 路线

Sinatra how use Rack::Protection::AuthenticityToken except for certain api routes

我正在尝试配置经典的 Sinatra 2.0.8.1 应用程序(“www.example.com”)以在某些但不是所有路线上使用 Rack::Protection,尤其是 Rack::Protection::AuthenticityToken

内部表单(在应用程序内)工作正常。每个表单都有一个隐藏的 CSRF 真实性令牌,因此应用程序 in 中的表单可以 POST 将数据路由 in 应用程序。

但是我找不到任何文档如何为某些路由排除或跳过 AuthenticityToken,以便 外部 应用程序可以 POST 数据到此应用程序。

在这种情况下,我们有一些其他应用程序('foo.example.com' 和 'bar.example.com')POST 数据的路由。但是,当我们实施 Rack::Protection::AuthenticityToken 所有这些路由时,现在 return 发布到 403 时。

我尝试了多种方法,例如 permitted_originsorigin_whitelist,如下所示,但没有外部应用程序可以 POST 向 Sinatra 应用程序发送数据,除非我禁用 Rack::Protection::AuthenticityToken 对于整个应用程序。

# foo.example.com
# doesnt work:
require 'rack/protection'
use Rack::Protection, permitted_origins: ["https://foo.example.com", "https://bar.example.com"]
set :protection, :origin_whitelist => ['https://foo.example.com', 'https://bar.example.com'], except: [:remote_token, :frame_options, :path_traversal] 
use Rack::Protection::AuthenticityToken
use Rack::Protection::RemoteReferrer

肯定有 一些 机制可以“省略”某些路由上对 CSRF 令牌的要求,例如 api 接收 POSTed 的路由数据?

虽然这个解决方案让我觉得很脏,但这是有效的:

  1. 将所有路由放在它们自己的 file/class 中(有点像 Rails 中的控制器)

  2. 我不想使用 CSRF 令牌的 (api) 路由,我在进行机架保护初始化之前 use 那个 class 文件。

  3. 包含我确实要保护免受 CSRF 影响的(正常)路由的 classes 得到 use 机架保护初始化之后.

use Rack::Protection
set :protection,  except: [:path_traversal]

# FIRST LOAD ROUTES *NOT* PROTECTED BY Rack::Protection::AuthenticityToken

use ApplicationController
use ApipostController # external POST routes to omit 

# NOW enable the AuthenticityToken protection

Rack::Protection::AuthenticityToken
use Rack::Protection::AuthenticityToken
use Rack::Protection::RemoteReferrer

# now LOAD NORMAL ROUTES TO BE PROTECTED BY Rack::Protection::AuthenticityToken

use FooController 
use BarController