mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-03-03 19:24:48 +08:00
Merge pull request #1330 from okriuchykhin/ok_SCI_2770
Add request rate throttling for API [SCI-2770]
This commit is contained in:
commit
e9b64b65a3
7 changed files with 34 additions and 1 deletions
1
Gemfile
1
Gemfile
|
@ -26,6 +26,7 @@ gem 'active_model_serializers', '~> 0.10.7'
|
|||
gem 'json-jwt'
|
||||
gem 'jwt', '~> 1.5'
|
||||
gem 'kaminari'
|
||||
gem 'rack-attack'
|
||||
|
||||
# JS datetime library, requirement of datetime picker
|
||||
gem 'momentjs-rails', '~> 2.17.1'
|
||||
|
|
|
@ -357,6 +357,8 @@ GEM
|
|||
public_suffix (3.0.2)
|
||||
puma (3.11.2)
|
||||
rack (2.0.5)
|
||||
rack-attack (5.4.1)
|
||||
rack (>= 1.0, < 3)
|
||||
rack-test (1.1.0)
|
||||
rack (>= 1.0, < 3)
|
||||
rails (5.1.6)
|
||||
|
@ -595,6 +597,7 @@ DEPENDENCIES
|
|||
pry-byebug
|
||||
pry-rails
|
||||
puma
|
||||
rack-attack
|
||||
rails (= 5.1.6)
|
||||
rails-controller-testing
|
||||
rails_12factor
|
||||
|
|
2
Makefile
2
Makefile
|
@ -85,7 +85,7 @@ tests-ci:
|
|||
@docker-compose run --rm web bash -c "bundle install && npm install"
|
||||
@docker-compose up -d webpack
|
||||
@docker-compose ps
|
||||
@docker-compose run -e ENABLE_EMAIL_CONFIRMATIONS=false -e MAILER_PORT=$MAILER_PORT -e SMTP_DOMAIN=$SMTP_DOMAIN -e SMTP_USERNAME=$SMTP_USERNAME -e SMTP_PASSWORD=$SMTP_PASSWORD -e SMTP_ADDRESS=$SMTP_ADDRESS -e PAPERCLIP_HASH_SECRET=PAPERCLIP_HASH_SECRET -e MAIL_SERVER_URL=localhost -e PAPERCLIP_STORAGE=filesystem -e ENABLE_RECAPTCHA=false -e ENABLE_USER_CONFIRMATION=false -e ENABLE_USER_REGISTRATION=true --rm web bash -c "rake db:create db:migrate && rake db:migrate RAILS_ENV=test && npm install && bundle exec rspec && bundle exec cucumber"
|
||||
@docker-compose run -e ENABLE_EMAIL_CONFIRMATIONS=false -e MAILER_PORT=$MAILER_PORT -e SMTP_DOMAIN=$SMTP_DOMAIN -e SMTP_USERNAME=$SMTP_USERNAME -e SMTP_PASSWORD=$SMTP_PASSWORD -e SMTP_ADDRESS=$SMTP_ADDRESS -e PAPERCLIP_HASH_SECRET=PAPERCLIP_HASH_SECRET -e MAIL_SERVER_URL=localhost -e PAPERCLIP_STORAGE=filesystem -e ENABLE_RECAPTCHA=false -e ENABLE_USER_CONFIRMATION=false -e ENABLE_USER_REGISTRATION=true -e CORE_API_RATE_LIMIT=1000000 --rm web bash -c "rake db:create db:migrate && rake db:migrate RAILS_ENV=test && npm install && bundle exec rspec && bundle exec cucumber"
|
||||
|
||||
console:
|
||||
@$(MAKE) rails cmd="rails console"
|
||||
|
|
|
@ -17,6 +17,7 @@ module Api
|
|||
attr_accessor :core_api_token_iss
|
||||
attr_accessor :azure_ad_apps
|
||||
attr_accessor :core_api_v1_preview
|
||||
attr_accessor :core_api_rate_limit
|
||||
|
||||
def initialize
|
||||
@core_api_sign_alg = 'HS256'
|
||||
|
@ -24,6 +25,7 @@ module Api
|
|||
@core_api_token_iss = 'SciNote'
|
||||
@azure_ad_apps = {}
|
||||
@core_api_v1_preview = false
|
||||
@core_api_rate_limit = 1000
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,6 +15,9 @@ module Scinote
|
|||
# Application configuration should go into files in config/initializers
|
||||
# -- all .rb files in that directory are automatically loaded.
|
||||
|
||||
# Add rack-attack middleware for request rate limiting
|
||||
config.middleware.use Rack::Attack
|
||||
|
||||
# Swap the Rack::MethodOverride with a wrapped middleware for WOPI handling
|
||||
require_relative '../app/middlewares/wopi_method_override'
|
||||
config.middleware.swap Rack::MethodOverride, WopiMethodOverride
|
||||
|
|
|
@ -9,6 +9,8 @@ Api.configure do |config|
|
|||
config.core_api_token_iss = ENV['CORE_API_TOKEN_ISS']
|
||||
end
|
||||
|
||||
config.core_api_rate_limit = ENV['CORE_API_RATE_LIMIT'].to_i || 1000
|
||||
|
||||
config.core_api_v1_preview = true if ENV['CORE_API_V1_PREVIEW']
|
||||
|
||||
Paperclip::DataUriAdapter.register if ENV['CORE_API_V1_PREVIEW']
|
||||
|
|
22
config/initializers/rack_attack.rb
Normal file
22
config/initializers/rack_attack.rb
Normal file
|
@ -0,0 +1,22 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Rack::Attack.throttle('api requests by ip',
|
||||
limit: Api.configuration.core_api_rate_limit,
|
||||
period: 60) do |request|
|
||||
request.ip if request.path =~ %r{^\/api\/}
|
||||
end
|
||||
|
||||
Rack::Attack.throttled_response = lambda do |env|
|
||||
match_data = env['rack.attack.match_data']
|
||||
now = match_data[:epoch_time]
|
||||
|
||||
headers = {
|
||||
'RateLimit-Limit' => match_data[:limit].to_s,
|
||||
'RateLimit-Remaining' => '0',
|
||||
'RateLimit-Reset' => (
|
||||
now + (match_data[:period] - now % match_data[:period])
|
||||
).to_s
|
||||
}
|
||||
|
||||
[429, headers, ["Throttled\n"]]
|
||||
end
|
Loading…
Reference in a new issue