[ruby on rails]rack-cors, rack-attack

ruby 复制代码
gem 'rack-attack'
gem 'rack-cors'

1. rack-attack 可以根据ip、域名等设置黑名单、设置访问频率

  • 设置黑名单
ruby 复制代码
# 新增 config/initializers/rack_attack.rb
# 请求referer如果匹配不上设置的allowed_origins,返回403 forbidden
Rack::Attack.blocklist('block bad domains') do |req|
  next if !req.path.start_with?('/admin_api/') || Rails.env.test?

  Rails.application.credentials.allowed_origins.none? { |r| Regexp.new(r) =~ req.referer }
end

# EDITOR="vim" bin/rails credentials:edit
allowed_origins:
  - api.xxx.net
  - localhost
  • 设置访问频率
ruby 复制代码
class Rack::Attack
  # Rack::Attack.cache.store = ActiveSupport::Cache::RedisCacheStore.new(url: "...")
  Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new
  # key: "rack::attack:#{Time.now.to_i/:period}:public_data/ip:#{req.ip}"
  throttle('public_data/ip', limit: 2, period: 1.minutes) do |req|
    req.ip if req.path.start_with?('/pc/v1/public_data')
  end

  self.throttled_responder = lambda do |_env|
    [429, # status
     {}, # headers
     ['throttling, retry later']] # body
  end
end

2. rack-cors 可以根据域名、访问方法、资源设置跨域请求cors

ruby 复制代码
# config/initializers/cors.rb

Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins '*'
    resource '*', headers: :any, methods: [:get, :post, :put, :patch, :delete, :options, :head],
  end
end
  • 复杂一些
ruby 复制代码
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins 'localhost:3000', '127.0.0.1:3000',
            /\Ahttp:\/\/192\.168\.0\.\d{1,3}(:\d+)?\z/
            # regular expressions can be used here

    resource '/file/list_all/', :headers => 'x-domain-token'
    resource '/file/at/*',
        methods: [:get, :post, :delete, :put, :patch, :options, :head],
        headers: 'x-domain-token',
        expose: ['Some-Custom-Response-Header'],
        max_age: 600
        # headers to expose
  end

  allow do
    origins '*'
    resource '/public/*', headers: :any, methods: :get

    # Only allow a request for a specific host
    resource '/api/v1/*',
        headers: :any,
        methods: :get,
        if: proc { |env| env['HTTP_HOST'] == 'api.example.com' }
  end
end
相关推荐
aibo86030815 小时前
基于 Spring Boot + Vue3 的餐饮食材采购与成本分析系统设计与实现
java·spring boot·后端
Rain的Java大神之路15 小时前
面了上百人,我最爱问的LeetCode 1「两数之和」:能背代码的很多,能讲清“先查后存”的没几个
java·后端·算法
aibo86030815 小时前
基于 Spring Boot + Vue3 的菜谱分享网站设计与实现
java·spring boot·后端
凤山老林15 小时前
Spring Boot 集成 TOTP 双因素认证与恢复码机制
java·spring boot·后端
vipxieliang15 小时前
ThinkPHP MVC 模式入门:从控制器到视图的完整实践
后端·php·thinkphp
vipxieliang16 小时前
Spring Boot 测试策略:单元测试、切片测试与集成测试
java·spring boot·后端
vipxieliang16 小时前
Go 1.24 工具链改进实战:工具依赖管理与 go vet 新分析器
后端·go
掘金者阿豪16 小时前
慢 SQL 优化别急着加索引:从订单分页查询聊聊 KES 执行计划
后端
涡能增压发动积16 小时前
AI 对一位老开发的副作用总结
后端
未秃头的程序猿16 小时前
同一个商户号,V2 免密代扣和 V3 分账的证书怎么共存?
java·后端·微信