Sinatra如何使用Rack :: Protection :: AuthenticityToken某些api路由除外

问题描述

我正在尝试将经典的Sinatra 2.0.8.1应用程序(“ www.example.com”)配置为在部分但并非全部路径上使用Rack::Protection,尤其是Rack::Protection::AuthenticityToken

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

但是我找不到任何文档来了解某些路由如何超越或跳过AuthenticityToken,以便外部应用可以将数据发布到该应用。

在这种情况下,我们有两个其他应用程序(“ foo.example.com”和“ bar.example.com”)将数据发布到的路由。但是,当我们实现Rack::Protection::AuthenticityToken时,所有这些路由在发布到时都会返回403。

我已经尝试了诸如permitted_originsorigin_whitelist之类的各种操作,如下所示,但是除非我整个禁用Rack::Protection::AuthenticityToken,否则任何外部应用都无法将数据发布到Sinatra应用中应用程序。

# 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

是否确实有 some 机制可以“忽略”某些路由(例如接收POST数据的api路由)对CSRF令牌的要求?

解决方法

尽管解决方案使我感到肮脏,但这是可行的:

  1. 将所有路由放入自己的文件/类(类似于Rails中的控制器)

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

  3. 在Rackprotection初始化之后,包含我想从CSRF保护的(普通)路由的类在{em> 之后得到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