S3 में डेटा को कैसे स्टोर करें और पटरियों एपीआई / आईओएस क्लाइंट के साथ सुरक्षित तरीके से उपयोगकर्ता की अनुमति दें?


93

मैं रेल और एपीआई लिखने के लिए नया हूं। मुझे S3 भंडारण समाधान के साथ कुछ मदद चाहिए। यहाँ मेरी समस्या है।

मैं एक iOS ऐप के लिए एक एपीआई लिख रहा हूं जहां उपयोगकर्ता iOS पर फेसबुक एपीआई के साथ लॉगिन करते हैं। सर्वर उपयोगकर्ता को टोकन फेसबुक मुद्दों के खिलाफ iOS उपयोगकर्ता के लिए मान्य करता है और एक अस्थायी सत्र टोकन जारी करता है। इस बिंदु से उपयोगकर्ता को S3 में संग्रहीत सामग्री को डाउनलोड करने की आवश्यकता होती है। यह सामग्री केवल उपयोगकर्ता और उसके दोस्तों के उपसमूह की है। यह उपयोगकर्ता S3 में अधिक सामग्री जोड़ सकता है जिसे लोगों के एक ही समूह द्वारा एक्सेस किया जा सकता है। मुझे लगता है कि यह एक फ़ाइल को फेसबुक समूह में संलग्न करने के समान है ...

उपयोगकर्ता द्वारा S3 के साथ इंटरेक्ट करने के 2 तरीके हैं ... इसे सर्वर पर छोड़ दें या अस्थायी S3 टोकन जारी करने के लिए सर्वर प्राप्त करें (यहां संभावनाओं के बारे में निश्चित नहीं) और उपयोगकर्ता सीधे S3 के लिए सामग्री URL पर हिट कर सकता है। मैंने इस सवाल को दृष्टिकोणों के बारे में बात करते हुए पाया, हालांकि, यह वास्तव में दिनांकित है (2 साल पहले): iPhone ऐप और S3 से फ़ोटो अपलोड करने के बारे में वास्तुशिल्प और डिज़ाइन प्रश्न

तो सवाल:

  • क्या एक उपयोगकर्ता को S3 पर केवल कुछ सामग्री तक पहुंचने के लिए सीमित करने का एक तरीका है जब एक अस्थायी टोकन जारी किया जाता है? मैं यह कैसे कर सकता हूँ? मान लें कि ... 100,000 या अधिक उपयोगकर्ता कहते हैं।
  • क्या आईओएस डिवाइस को इस सामग्री को सीधे बाहर खींचने देना अच्छा है?
  • या सर्वर को पास होने वाली सभी सामग्री को नियंत्रित करने देना चाहिए (यह निश्चित रूप से सुरक्षा को हल करता है)? क्या इसका मतलब है कि मुझे कनेक्टेड उपयोगकर्ताओं को सौंपने से पहले सर्वर को सभी सामग्री डाउनलोड करनी होगी?
  • यदि आप रेल को जानते हैं ... तो क्या मैं इस तरह का सेटअप हासिल करने के लिए पेपरक्लिप और अर्स-एसडीके रत्नों का उपयोग कर सकता हूं?

कई सवालों के लिए माफी और मैं समस्या में किसी भी अंतर्दृष्टि की सराहना करता हूं। धन्यवाद :)


1
यह पाया और सोचा कि मैं दूसरों के लिए टिप्पणी करूँगा docs.aws.amazon.com/AmazonS3/latest/dev/…
dibble

जवाबों:


113

Aws-sdk रत्न का उपयोग करके , आप कॉल करके किसी भी S3 ऑब्जेक्ट के लिए एक अस्थायी हस्ताक्षरित url प्राप्त कर सकते हैं url_for:

s3 = AWS::S3.new(
  :access_key_id => 1234,
  :secret_access_key => abcd
)
object = s3.buckets['bucket'].objects['path/to/object']
object.url_for(:get, { :expires => 20.minutes.from_now, :secure => true }).to_s

यह आपको S3 में केवल उस ऑब्जेक्ट के लिए एक हस्ताक्षरित, अस्थायी उपयोग URL देगा। यह 20 मिनट (इस उदाहरण में) के बाद समाप्त हो रहा है, और यह केवल उस एक वस्तु के लिए अच्छा है।

यदि आपके पास ग्राहक की बहुत सारी वस्तुएँ हैं, तो आपको बहुत सारे हस्ताक्षरित URL जारी करने होंगे।

या सर्वर को पास होने वाली सभी सामग्री को नियंत्रित करने देना चाहिए (यह निश्चित रूप से सुरक्षा को हल करता है)? क्या इसका मतलब है कि मुझे कनेक्टेड उपयोगकर्ताओं को सौंपने से पहले सर्वर को सभी सामग्री डाउनलोड करनी होगी?

ध्यान दें कि इसका मतलब यह नहीं है कि सर्वर को प्रत्येक ऑब्जेक्ट को डाउनलोड करने की आवश्यकता है, इसे केवल S3 में विशिष्ट वस्तुओं तक पहुंचने के लिए विशिष्ट ग्राहकों को प्रमाणित और अधिकृत करने की आवश्यकता है।

Amazon से API डॉक्स: https://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html#RESTAuthenticationQueryStringAuth


3
इसके लिए धन्यवाद @ejdyksen। मैंने जो समाधान तैयार किया है, वह बिल्कुल सही है (मैंने अपने उत्तर के साथ प्रश्न को अपडेट नहीं किया है)! तो मेरा समाधान GET अनुरोधों के लिए प्रमाणित URL करना था। हालाँकि, जब कोई उपयोगकर्ता सामग्री में योगदान देता है, तो वह एक विशिष्ट / बाल्टी / उपयोगकर्ता / ऑब्जेक्टनाम स्थान के लिए संसाधनों का निर्माण करता है जो फेडरेटेड IAM टोकन (अस्थायी क्रेडेंशियल्स जो समाप्त हो जाते हैं) / बाल्टी / उपयोगकर्ता / * लिखने की अनुमति के लिए संलग्न नीति के साथ उपयोग करते हैं। इसलिए सिस्टम का कोई भी उपयोगकर्ता अन्य उपयोगकर्ताओं की सामग्री को नुकसान नहीं पहुंचा सकता है। ठीक काम करने लगता है। आपके उत्तर की सराहना करते हैं।
दिन

5
यदि आप a2-sdk-ruby के v2 का उपयोग कर रहे हैं, तो ध्यान दें कि विधियाँ कुछ भिन्न हैं: docs.aws.amazon.com/sdkforruby/api/Aws/S3/…
vijucha

2
क्या यह जोखिम नहीं है कि उपयोगकर्ता मेरी पहुंच कुंजी देख सकता है? गुप्त कुंजी (परिवर्तित) भी है
user2503775

3
@ पूरा बिंदु यह है कि फ़ाइल को आपके सर्वर से टकराना नहीं है। लिंक में आपका AWS क्रेडेंशियल नहीं है। इसमें शामिल हो सकता है ACCESS_KEY_ID(मुझे अपने सिर के ऊपर से याद नहीं है), लेकिन यह एक रहस्य होने का इरादा नहीं है।
एजडेकन

2
@ejdyksen आप सही हैं, मैंने अभी सत्यापित किया है कि URL में केवल शामिल है AWS_ACCESS_KEY_ID। मैंने मूल रूप से सोचा था कि AWS_SECRET_ACCESS_KEYयह भी प्रदर्शित किया गया था लेकिन यह नहीं है।
डेनिस

46

उपरोक्त उत्तर नए aws-sdk-resource संस्करण 2 के बजाय पुराने aws-sdk-v1 मणि का उपयोग करते हैं।

नया तरीका है:

aws_resource = Aws::S3::Resource::new
aws_resource.bucket('your_bucket').object('your_object_key').presigned_url(:get, expires_in: 1*20.minutes)

जहाँ आपकी_object_key आपकी फ़ाइल का पथ है। यदि आपको यह देखने की आवश्यकता है, तो आप कुछ इस तरह का उपयोग करेंगे:

s3 = Aws::S3::Client::new
keys = []
s3.list_objects(bucket: 'your_bucket', prefix: 'your_path').contents.each { |e| 
  keys << e.key
}

यह जानकारी खुदाई के लिए चौंकाने वाली मुश्किल थी, और मैंने लगभग सिर्फ पुराने मणि का इस्तेमाल किया।

संदर्भ

http://docs.aws.amazon.com/sdkforruby/api/Aws/S3/Object.html#presigned_url-instance_method


1
expires_inसेकंड के रूप में डेटा की अपेक्षा करता है, बस पहले इसे परिवर्तित करना सुनिश्चित करें।
frillybob

"तर्कपरिवर्तन (अपेक्षित: समय समाप्त होने की संख्या
समाप्त हो रही है
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.