2011-04-05 3 views
12

Il s'agit d'une question en deux parties. Je dois limiter un site de rails que je lance sur le serveur de développement à seulement quelques adresses IP, donc le public ne peut pas y accéder. (L'authentification HTTP de base ne fonctionne pas «entièrement» car l'autorisation casse un uploader Flash dans le projet.)Rails 3 - Liste blanche des adresses IP via les routes

D'après ce que j'ai googlé, c'est ce que j'ai trouvé dans mon fichier de routes.

class WhitelistConstraint 
    def initialize 
    @ips = '127.0.0.1' 
    end 

    def matches?(request) 
    @ips.include?(request.remote_ip) 
    end 
end 

MyProject::Application.routes.draw do 
    constraints WhitelistConstraint.new do 
    # all my routing stuff here 
    end 
end 

Fonctionne plutôt bien. Cependant, j'ai besoin de le modifier pour travailler avec plusieurs adresses IP. J'ai essayé d'utiliser un tableau sur @ips, ainsi que de boucler chaque boucle, mais aucun n'a fonctionné. En plus de cela, la deuxième partie de ma question ... Je pourrais avoir besoin de vérifier seulement par rapport à un segment de l'IP, comme '127.0.0'. Comment ferais-je cela?

Répondre

25

Je ne savais pas que vous pouvez le faire par des voies, serait d'avoir juste mon approche un before_filter dans le ApplicationController et juste quelque chose qui fait:

before_filter :protect 

def protect 
    @ips = ['127.0.0.1', '203.123.10.1'] #And so on ...] 
    if not @ips.include? request.remote_ip 
    # Check for your subnet stuff here, for example 
    # if not request.remote_ip.include?('127.0,0') 
    render :text => "You are unauthorized" 
    return 
    end 
end 
+0

Je n Je ne sais pas non plus. Cependant, cette solution a fonctionné tout de suite pour moi et probablement la meilleure route à suivre. Il pourrait y avoir un problème sur le passage du développement à la production (qui est temporairement le serveur de transfert), mais c'est seulement temporaire et je peux juste ajouter les adresses IP sur les deux environnements si nécessaire. Merci. – Shannon

+0

Vous pouvez utiliser 'Rails.env.production?' Et 'Rails.env.development?' Pour vérifier l'environnement dans une sorte de construction 'if' en fonction de ce que vous devez faire. Bonne chance :) –

+0

Est-ce que cette solution fonctionnerait pour les plages IP? – DanielCW

7

ce que sur l'utilisation NetAddr::CIDR?

et quelque chose comme ça?

class WhitelistConstraint 
    def initialize 
    @ips = [] 
    @ips << NetAddr::CIDR.create('127.0.0.0/8') 
    @ips << NetAddr::CIDR.create('192.168.0.0/16') 
    end 

    def matches?(request) 
    valid = @ips.select {|cidr| cidr.contains?(request.remote_ip) } 
    !valid.empty? 
    end 
end 

MyProject::Application.routes.draw do 
    constraints WhitelistConstraint.new do 
    # all my routing stuff here 
    end 
end 

De cette façon, vous pouvez spécifier les blocs d'adresses IP qui devraient être dans la liste blanche, et ne pas avoir à se soucier des correspondances partielles?

>> require 'netaddr' 
=> true 
>> @ips = [] 
=> [] 
>> @ips << NetAddr::CIDR.create('127.0.0.0/8') 
=> [127.0.0.08] 
>> @ips << NetAddr::CIDR.create('192.168.0.0/16') 
=> [127.0.0.08, 192.168.0.016] 
>> @ips.select { |c| c.contains? '192.168.10.1' } 
=> [192.168.0.016] 
>> @ips.select { |c| c.contains? '192.169.10.1' } 
=> [] 
+0

N'a pas fonctionné pour moi, a une erreur 'non-initialisée constante WhitelistConstraint :: NetAddr' – Shannon

+0

Vous devrez ajouter la Gemme NetAddr Gemfile à vous si vous utilisez les rails 3 et faire la danse de paquet :) ou mettre à jour votre gem config si sur les rails 2. – Doon

+0

Ah ça va, ça a du sens ... J'ai trouvé une solution alternative ci-dessus et c'est probablement mieux car c'est seulement une chose "temporaire" pour les tests internes, mais je garderai ça en tête si j'ai besoin de quelque chose – Shannon

1

Ou tout simplement utiliser .htaccess apache:

  1. Ajouter ce qui suit à l'http.conf ou tout autre fichier que vous avez pour conf apache et votre application rails

AllowOverride tous

  1. Créer un fichier .htaccess dans les rails dossier et ajouter ce qui suit
Allow from xxx.xxx.xxx.xxx 
Deny from all 
+0

Avait essayé cette première sans succès, et il était à la recherche de rails .htaccess que quelqu'un a suggéré d'utiliser des routes à la place, qui est ce que Mais, maintenant que vous le mentionnez, je n'ai peut-être pas eu le AllowOverride dans mon http.conf – Shannon

+0

Donc, ça a marché? –

+0

Je n'ai pas eu le temps de faire un essai car j'y suis allé avec une autre solution, mais il va y avoir un point dans le projet où j'aurai besoin du fichier .htaccess, donc cela sera très utile. – Shannon

1

Il est également possible d'entourer votre déclaration d'itinéraire avec une portée comme ceci:

scope :constraints => lambda{|req|%w(127.0.0.1).include? req.remote_addr} do 

    ... your beautiful routes 

end