我正在使用 Sinatra 框架在 ruby 中构建一个简单的应用程序。它主要基于“获取”——大多数请求都是针对列表数据的。然而,应用程序中有几个关键屏幕将收集用户输入。我想确保应用程序尽可能安全,目前正在尝试找到如何实现以 Rails 形式获得的真实性令牌类型?
我必须去的地方: 好吧,我知道我需要 csrf 的令牌,但我不确定是否需要自己生成它们,或者 Sinatra 是否可以为我生成 - 我已经查看了文档,他们说 Sinatra 正在使用机架保护,但是,我找不到它的任何示例代码,并且似乎不知道如何让它运行 - 任何帮助appreciated - 谢谢!
rack_csrf
宝石。安装它
gem install rack_csrf
rack_csrf
gem 有一个 Sinatra 示例。以下是改编自此页面的更简单示例(似乎离线。存档版本):
require "rack/csrf"
configure do
use Rack::Session::Cookie, :secret => "some unique secret string here"
use Rack::Csrf, :raise => true
end
使用
enable :sessions
代替 use Rack::Session::Cookie ...
在大多数情况下也有效(请参阅 Bill 的评论)。
在您看来,您可以使用
Rack::Csrf.csrf_token
和 Rack::Csrf.csrf_tag
方法获取令牌(或标签)。如果这看起来很长,您可能需要按照以下方式定义一个助手:
helpers do
def csrf_token
Rack::Csrf.csrf_token(env)
end
def csrf_tag
Rack::Csrf.csrf_tag(env)
end
end
使用辅助方法的小示例:
<form method="post" action="/tweet">
<%= csrf_tag %>
<input type="text" name="message"/>
<input type="submit" value="Submit a tweet!"/>
</form>
当渲染相同的 erb 视图时,在登录时凭据无效的情况下。现在在提交渲染后会抛出错误。
Rack::Csrf::InvalidCsrfToken at /login
Rack::Csrf::InvalidCsrfToken
我们是否需要进行重定向来代替渲染才能完成这项工作?因为在渲染中旧的 csrf 令牌仍然存在。在完整的重定向中,我们生成了一个新令牌。
您可以使用
Rack::Protection
和 Rack::Protection::AuthenticityToken
来实现此目的。
这是简化的示例:
class MyApp < Sinatra::Base
use Rack::Protection
use Rack::Protection::AuthenticityToken
helpers do
def csrf_tag
"<input type='hidden' name='authenticity_token' value='#{session[:csrf]}' />"
end
end
get "/login" do
erb :login
end
post "/login" do
# handle login logic
end
end
<form action="/login" method="post">
<%= csrf_tag %>
<label>
Email:
<input type="email" name="email" required>
</label>
<label for="password">
Password:
<input type="password" name="password" required>
</label>
<button type="submit">
Login
</button>
</form>