Rails 5:使用PURE代码获取网络IP地址范围

时间:2018-09-15 17:08:36

标签: ruby ruby-on-rails-5

我想将对特定控制器中网站某些页面的访问限制为某个IP地址范围,我想出了解决办法,但找不到使用 PURE 代码...仍然可以吗?

2 个答案:

答案 0 :(得分:1)

class SomeController < ApplicationController
  before_action :restrict_access, only: %i( action1 )

  def action1
    # something
  end

  def action2
    # something else
  end

  private

  def restrict_access
    unless TRUSTED_IPS.include? request.remote_ip
      flash[:error] = "Sorry. You are not allowed."
      redirect_to root_path
    end 
  end

  TRUSTED_IPS = [
    "192.168.1.13",
    "192.168.1.19",
  ]
end

这将允许您限制对特定IP的访问。如果要限制为单个IP范围,也可以执行以下操作:

private

def restrict_access
  if !( ip_to_int(request.remote_ip) > ip_to_int(MIN_IP) 
    and ip_to_int(request.remote_ip) < ip_to_int(MAX_IP) )
    flash[:error] = "Sorry. You are not allowed."
    redirect_to root_path
  end
end

def ip_to_int(ip)
  request.remote_ip.split(".").map{|el| el.rjust(3,'0')}.join.to_i
end

MIN_IP = "192.168.0.13"
MAX_IP = "192.168.0.46"

答案 1 :(得分:1)

您可以从request.remote_ip中找到发出请求的客户端的IP。

然后定义一个自定义约束,以限制对某些IP或IP范围的访问。

您的route.rb文件如下所示

require "ipaddr"

MyApp::Application.routes.draw do
  resources :users

  constraints Whitelist.new do
     get 'protected_routes'
  end

end

class WhiteList
  def initialize
    @ips = ['127.0.0.1', '203.123.10.1']
    @ip_ranges = [
                   {
                     start_ip: '192.168.0.1',
                     end_ip:   '192.168.0.30'
                   },

                   {
                     start_ip: '10.1.1.1',
                     end_ip:   '10.1.1.100'
                   }
                 ]
  end

  def matches?(request)
    return true if @ips.include? request.remote_ip

    remote_ip_address = IPAddr.new(request.remote_ip).to_i

    @ip_ranges.each do |ip_range|
        low  = IPAddr.new(ip_range[:start_ip]).to_i
        high = IPAddr.new(ip_range[:end_ip]).to_i
        return true if (low..high)===remote_ip_address
    end

    return false
  end

end