2009-10-21 16 views
13

मैं एक रेल एप्लिकेशन लिखना शुरू कर रहा हूं जो ग्राहकों को हमारे आवेदन तक पहुंच के लिए एक अलग सबडोमेन रखने की अनुमति देगा। डेटा सुरक्षा दृष्टिकोण से सोचते हुए, यह अच्छा होगा अगर प्रत्येक ग्राहक की पहुंच वास्तव में उनके डेटाबेस तक सीमित थी, इस तरह, अगर उत्पादन कोड में कोई बग है, तो वे केवल अपने डेटाबेस तक पहुंच पाएंगे, न कि किसी अन्य के ग्राहकों।रेल - प्रति सबडोमेन अलग डेटाबेस

मुझे पता है कि मैं क्या चाहता हूं इसके पीछे कोड जानता हूं, लेकिन मैं सोच रहा था कि क्या एक आसान समाधान था जो मुझे याद आ रहा है। आप क्लाइंट डेटा को सुरक्षित करने के बारे में कैसे जाएंगे ताकि बग या हैकर खतरे की स्थिति में, उनके डेटा का खुलासा होने की संभावना कम होगी?

उत्तर

20

यहाँ कुछ कोड मैं इस बहुत समस्या के लिए उपयोग है!

+0

+1 - निश्चित रूप से बहुत उपयोगी। क्या आप मुझे इस दृष्टिकोण के साथ प्रदर्शन हिट (यदि कोई ध्यान देने योग्य) का विचार दे सकते हैं? –

+0

क्षमा करें मेरे पास इसके बारे में कोई बेंचमार्क नहीं है। इस समय मैं केवल एक निजी बीटा पर काम कर रहा हूं। – Kris

+0

किसी के पास कोई अटकलें हैं कि क्या यह एक भयानक प्रदर्शन हिट करेगा या नहीं? मैं उत्पादन साइट के लिए कुछ ऐसा करना चाहता हूं। – NotDan

0

मेरे सिर के ऊपर से आप विभिन्न वातावरण का उपयोग करके प्रत्येक सबडोमेन के लिए एक नया सर्वर उदाहरण चला सकते हैं।

लेकिन यह बहुत अच्छी तरह से स्केल नहीं करेगा।

हालांकि पहले कुछ google hits for multiple rails databases कुछ नए सुझावों को चालू करते हैं। उन लिंक में जानकारी एकत्र करने से एक सर्वर उदाहरण के लिए यह पूरी तरह से अवांछित समाधान प्रदान करता है।

आपको अपने डेटाबेस में प्रत्येक सबडोमेन के लिए डेटाबेस प्रविष्टि जोड़ने की आवश्यकता होगी .yml। फिर अपने एप्लिकेशन नियंत्रक

अपडेट में पहले_फिल्टर जोड़ें! उदाहरण गतिशील रूप से डेटाबेस कॉन्फ़िगरेशन को पुनः लोड करता है। दुर्भाग्यवश आपके सर्वर के आंतरिक के साथ गड़बड़ किए बिना अपडेट रेल को व्यापक बनाने का कोई अच्छा तरीका नहीं है। इसलिए प्रत्येक अनुरोध पर डेटाबेस कॉन्फ़िगरेशन को पुनः लोड करना होगा।

यह उदाहरण डेटाबेस में डेटाबेस प्रविष्टियों को मानता है। आईडीएल को सबडोमेन के नाम पर रखा गया है।

config/database.yml

login: &login 
    adapter: mysql 
    username: rails 
    password: IamAStrongPassword! 
    host: localhost 

production: 
    <<: *login 
    database: mysite_www 

subdomain1: 
    <<: *login 
    database: mysite_subdomain1 

subdomain2: 
    <<: *login 
    database: mysite_subdomain2 
... 

एप्लिकेशन/नियंत्रक/application_controller.rb की आवश्यकता होती है 'ERB' before_filter: switch_db_connection

def switch_db_connection 
    subdomain = request.subdomains.first 
    ActiveRecord::Base.configurations = YAML::load(ERB.new(IO.read(Rails.configuration.database_configuration_file)).result) 
    ActiveRecord::Base.establish_connection("mysite_#{subdomain}") 
end 

जैसा कि मैंने कहा यह पूरी तरह से अपरीक्षित है। लेकिन मुझे किसी भी बड़ी समस्या का पता नहीं लगा है। अगर यह उम्मीद नहीं करता है कि यह आपको सही रास्ते पर रखता है।

+1

इसके साथ समस्या यह है कि जब आप एक नया सबडोमेन जोड़ते हैं तो आपको सभी सर्वर इंस्टेंस को पुनरारंभ करने की आवश्यकता होगी। यदि आप एक साथ बहुत सारे सबडोमेन जोड़ रहे हैं, तो इसका मतलब कुछ डाउनटाइम होगा। –

+1

उदाहरण को एक सर्वर उदाहरण में गतिशील बनाया गया। हालांकि यह अभी भी अनचाहे है। – EmFi

0

बाहर निकलता है मैंने अभी really similar question से पूछा लेकिन विकास के साथ काफी आगे - मैंने इसमें तीन डेटाबेस भी सुरक्षित रूप से एक डेटाबेस का उपयोग करने के बारे में बताया है।

application_controller.rb

before_filter :set_database 

helper_method :current_website 

# I use the entire domain, just change to find_by_subdomain and pass only the subdomain 
def current_website  
    @website ||= Website.find_by_domain(request.host) 
end 

def set_database 
    current_website.use_database 
end 

# Bonus - add view_path 
def set_paths 
    self.prepend_view_path current_website.view_path unless current_website.view_path.blank? 
end 

Website.rb

def use_database 
    ActiveRecord::Base.establish_connection(website_connection) 
end 

# Revert back to the shared database 
def revert_database 
    ActiveRecord::Base.establish_connection(default_connection) 
end 

private 

# Regular database.yml configuration hash 
def default_connection 
    @default_config ||= ActiveRecord::Base.connection.instance_variable_get("@config").dup 
end 

# Return regular connection hash but with database name changed 
# The database name is a attribute (column in the database) 
def website_connection 
    default_connection.dup.update(:database => database_name) 
end 

आशा इस मदद करता है:

+0

लिंक के लिए धन्यवाद। मुझे कुछ विचार देता है, लेकिन ऐसा लगता है कि अभी तक इस समस्या के लिए वास्तव में कोई अच्छा समाधान नहीं है। –

4

मैं एक अलग समाधान है कि थोड़ा आसान काम करता है पाया है, लेकिन इस धारणा है कि आप प्रत्येक उप डोमेन के लिए एक डेटाबेस है बनाता है:

application_controller।आरबी

before_filter :subdomain_change_database 

def subdomain_change_database 
    if request.subdomain.present? && request.subdomain != "www" 
    # 'SOME_PREFIX_' + is optional, but would make DBs easier to delineate 
    ActiveRecord::Base.establish_connection(website_connection('SOME_PREFIX_' + request.subdomain)) 
    end 
end 

# Return regular connection hash but with database name changed 
# The database name is a attribute (column in the database) 
def website_connection(subdomain) 
    default_connection.dup.update(:database => subdomain) 
end 

# Regular database.yml configuration hash 
def default_connection 
    @default_config ||= ActiveRecord::Base.connection.instance_variable_get("@config").dup 
end 

यह mydb_subdomain की तरह एक डेटाबेस में बदल जाएगी। यह एक पूर्ण प्रतिस्थापन डेटाबेस विकल्प है, लेकिन यह कई संस्करणों को रोल करना बहुत आसान बनाता है।

संबंधित मुद्दे