2010-09-22 23 views
9

मैं पेपरक्लिप यूआरएल सुरक्षित बनाने का सबसे अच्छा तरीका खोजने की कोशिश कर रहा हूं, लेकिन केवल सुरक्षित पृष्ठों के लिए।केवल सुरक्षित पृष्ठों के लिए सुरक्षित पेपरक्लिप यूआरएल

उदाहरण के लिए, मुखपृष्ठ, जो एस 3 में संग्रहीत छवियों को दिखाता है, http://mydomain.com है और छवि यूआरएल http://s3.amazonaws.com/mydomainphotos/89/thisimage.JPG?1284314856 है।

मेरे पास https://mydomain.com/users/my_stuff/49 जैसे सुरक्षित पृष्ठ हैं जिनमें S3 में संग्रहीत छवियां हैं, लेकिन S3 प्रोटोकॉल http है और https नहीं है, इसलिए उपयोगकर्ता को ब्राउज़र से चेतावनी मिलती है कि पृष्ठ पर कुछ तत्व सुरक्षित नहीं हैं, ब्ला ब्ला ब्लाह ।

मुझे पता है कि मैं मॉडल में s3_protocol निर्दिष्ट कर सकता हूं, लेकिन यह आवश्यक होने पर भी सब कुछ सुरक्षित बनाता है। इसलिए, मैं केवल सुरक्षित पृष्ठों के लिए, फ्लाई पर https में प्रोटोकॉल को बदलने का सबसे अच्छा तरीका ढूंढ रहा हूं।

एक (शायद बुरा) जिस तरह की तरह एक नया यूआरएल विधि बनाने के लिए होगा: नोट करने के लिए

def custom_url(style = default_style, ssl = false) 
    ssl ? self.url(style).gsub('http', 'https') : self.url(style) 
end 

एक बात है कि मैं ssl_requirement प्लगइन का उपयोग कर रहा है, इसलिए यह टाई के लिए एक रास्ता हो सकता है है उसके साथ में

मुझे यकीन है कि ऐसा करने के लिए कुछ सरल, मानक तरीका है जिसे मैं देख रहा हूं, लेकिन मुझे यह प्रतीत नहीं होता है।

+0

हाय Shagymoe (मैं इसे रैक :: रनटाइम के बाद जोड़ा)। .. मुझे यह जानने में बहुत दिलचस्पी है कि आपका अंतिम समाधान कौन सा था :) – zetarun

+0

पेपरक्लिप जिथब मुद्दा यहां: https://github.com/thoughtbot/paperclip/issues/387 – swrobel

उत्तर

7

यदि रेल 2.3.x या नए का उपयोग करते हैं, तो आप उपयोगकर्ता को वापस भेजने से पहले प्रतिक्रिया फ़िल्टर करने के लिए रेल मिडलवेयर का उपयोग कर सकते हैं। इस तरह आप यह पता लगा सकते हैं कि वर्तमान अनुरोध एक HTTPS अनुरोध है और तदनुसार s3.amazonaws.com पर कॉल संशोधित करें।

paperclip_s3_url_rewriter.rb नामक एक नई फ़ाइल बनाएं और उसे उस निर्देशिका के अंदर रखें जो सर्वर प्रारंभ होने पर लोड हो। lib direcotry काम करेगा, लेकिन कई app/middleware निर्देशिका बनाना पसंद करते हैं और इसे रेल एप्लिकेशन लोड पथ में जोड़ना पसंद करते हैं।

नई फ़ाइल में निम्न वर्ग जोड़ें:

class PaperclipS3UrlRewriter 
    def initialize(app) 
    @app = app 
    end 

    def call(env) 
    status, headers, response = @app.call(env) 
    if response.is_a?(ActionController::Response) && response.request.protocol == 'https://' && headers["Content-Type"].include?("text/html") 
     body = response.body.gsub('http://s3.amazonaws.com', 'https://s3.amazonaws.com') 
     headers["Content-Length"] = body.length.to_s 
     [status, headers, body] 
    else 
     [status, headers, response] 
    end 
    end 
end 

तो बस नई मिडलवेयर रजिस्टर:

रेल 2.3.x: Rails::Initializer.run की शुरुआत में environment.rb के लिए नीचे पंक्ति जोड़ें ब्लॉक।
रेल 3.x: आवेदन कक्षा की शुरुआत में application.rb पर नीचे दी गई रेखा जोड़ें।

config.middleware.use "PaperclipS3UrlRewriter" 

अद्यतन:
मैं बस अपना जवाब संपादित और अगर बयान में response.is_a?(ActionController::Response) का चेक गयी। कुछ मामलों में (शायद संबंधित कैशिंग) प्रतिक्रिया ऑब्जेक्ट एक खाली सरणी (?) है और इसलिए request पर कॉल होने पर विफल रहता है।

अद्यतन 2: मैं रैक/मिडिलवेयर कोड उदाहरण संपादित ऊपर भी Content-Length हैडर अद्यतन करने के लिए। अन्यथा अधिकांश ब्राउज़रों द्वारा HTML निकाय काटा जाएगा।

+3

हर किसी में एक एस 3 यूआरएल-रीइटरर इंजेक्ट करना दुर्भाग्यपूर्ण लगता है जी के लिए तर्क को encapsulating के बजाय आपका आवेदन एक अनुरोध है उचित यूआरएल को पहले स्थान पर रखें। – Winfield

+0

वास्तव में @Winfield, प्रत्येक प्रतिक्रिया निकाय में एक अनबाउंड नियमित अभिव्यक्ति का मूल्यांकन पीछे की तरफ है। एक समाधान का उपयोग करें जो सही यूआरएल को पहली जगह उत्पन्न करता है। – Mars

1

एक नियंत्रक वर्ग में निम्न कोड का उपयोग करें:

# locals/arguments/methods you must define or have available: 
# attachment - the paperclip attachment object, not the ActiveRecord object 
# request - the Rack/ActionController request 
AWS::S3::S3Object.url_for \ 
    attachment.path, 
    attachment.options[:bucket].to_s, 
    :expires_in => 10.minutes, # only necessary for private buckets 
    :use_ssl => request.ssl? 

आप निश्चित रूप से यह एक विधि में लपेट कर सकते हैं अच्छी तरह से।

14

अगर कोई इस पर अब ठोकर खा रहा है: April 2012 के बाद से है! सीधे शब्दों में लिखें: एक प्रारंभकर्ता में

Paperclip::Attachment.default_options[:s3_protocol] = "" 

या अपने मॉडल के अंदर s3_protocol विकल्प का उपयोग करें।

इसे शुरू करने के लिए @ थॉमस वाटसन के लिए धन्यवाद।

+0

यह योजना-कम यूआरएल अब करने का आधिकारिक तरीका है। – Karew

+1

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

+0

यह भी देखें http://www.rubydoc.info/github/thoughtbot/paperclip/Paperclip/Storage/S3 –

0

एफवाईआई - ऊपर दिए गए कुछ उत्तर रेल 3+ के साथ काम नहीं करते हैं, क्योंकि एक्शनकंट्रोलर :: प्रतिक्रिया को हटा दिया गया है। निम्नलिखित का उपयोग करें:

class PaperclipS3UrlRewriter 
    def initialize(app) 
    @app = app 
    end 

    def call(env) 
    status, headers, response = @app.call(env) 
    if response.is_a?(ActionDispatch::BodyProxy) && headers && headers.has_key?("Content-Type") && headers["Content-Type"].include?("text/html") 
    body_string = response.body[0] 
    response.body[0] = body_string.gsub('http://s3.amazonaws.com', 'https://s3.amazonaws.com') 
    headers["Content-Length"] = body_string.length.to_s 
    [status, headers, response] 
    else 
    [status, headers, response] 
    end 
end 

अंत

और सुनिश्चित करें कि आप ढेर में एक अच्छी जगह में मिडलवेयर जोड़ने

config.middleware.insert_after Rack::Runtime, "PaperclipS3UrlRewriter" 
संबंधित मुद्दे