2011-01-17 15 views
11

मैं फेसबुक एपीआई और रूबी पर रूबी के साथ काम कर रहा हूं और मैं वापस आने वाले जेएसओएन को पार्स करने की कोशिश कर रहा हूं। जिस समस्या में मैं चल रहा हूं वह यह है कि फेसबुक base64URL उनके डेटा को एन्कोड करता है। रुबी के लिए कोई अंतर्निहित बेस 64URL डीकोड नहीं है।बेस 64 यूआरएल रूबी/रेल के साथ डीकोड?

बेस 64 एन्कोडेड और बेस 64URL एन्कोडेड, see wikipedia के बीच अंतर के लिए।

रूबी/रेल का उपयोग करके मैं इसे कैसे डीकोड कर सकता हूं?

संपादित:

क्योंकि कुछ लोगों को पढ़ने में परेशानी है - बेस 64 यूआरएल बेस 64 से अलग है

उत्तर

5

के लिए "बेस 64 के लिए Googling यूआरएल रूबी "और पहला परिणाम चुनने से मुझे the answer

cipher_token = encoded_token.tr('-_','+/').unpack('m')[0] 

cipher_token का विवरण महत्वपूर्ण नहीं है कि इसमें बाइट मान हो सकते हैं।

आप निश्चित रूप से base64UrlDecode(data) पर एक सहायक बना सकते हैं।

क्या हो रहा है कि यह encoded_token लेता है और + और / क्रमश: के साथ सभी - और _ पात्रों की जगह है। फिर, यह बेस 64-एन्कोडेड डेटा को unpack('m') के साथ डीकोड करता है और लौटाए गए सरणी में पहला तत्व देता है: आपका डीकोडेड डेटा।

+0

हाँ, मैंने यह http://www.ruby-forum.com/topic/167232 देखा, लेकिन यह मेरा पहला परिणाम नहीं था। मेरे लिए दूसरा पृष्ठ .. वैसे भी। मुझे समझ में नहीं आता कि वास्तव में क्या करता है ... मुझे अन्य तरीकों से जाना होगा – sethvargo

+0

मैंने सोचा था कि आप उस डेटा को डीकोड करना चाहते हैं जो फेसबुक आपको भेज रहा है ...?ऊपर दिए गए उदाहरण में, 'encoded_token' वह है जो फेसबुक आपको भेज रहा है और' cipher_token' डीकोडेड परिणाम है। – davemyron

+0

पैडिंग को संभालने के तरीके के कारण आपको इस समाधान के साथ एक विकृत JSON त्रुटि मिल सकती है। समाधान के लिए http://qugstart.com/blog/ruby-and-rails/facebook-base64-url-decode-for-signed_request/ देखें। – pschang

5

लिए base64URL एन्कोड स्ट्रिंग s ...

s.tr('+/', '-_').unpack('m')[0] 
+0

शायद ... यह क्या कर रहा है? मैं रूबी में काफी अच्छा हूं, लेकिन तुमने मुझे हरा दिया है। – sethvargo

+0

यह '+' से '-' और'/'से' _' में अनुवाद करता है, जो सादे बेस 64 उत्पन्न करना चाहिए, और फिर यह अंतर्निहित बेस 64 अनपैकर का उपयोग करता है, जो मुझे लगता है, एक तत्व तत्व सरणी है, इसलिए हम '[0]' के साथ वास्तविक स्ट्रिंग परिणाम प्राप्त करें। आप '[0] 'को' .first' – DigitalRoss

+0

'से बदल सकते हैं ऐसा लगता है कि आप दूसरी तरफ भी जा सकते हैं और बेस 64-एन्कोडेड स्ट्रिंग को base64URL में' s.tr ('-_', '+ /') के साथ परिवर्तित कर सकते हैं। – DigitalRoss

3

इस तरह मैं अपने फेसबुक आवेदन की signed_request पार्स है

def decode_facebook_hash(signed_request) 
    signature, encoded_hash = signed_request.split('.') 
    begin 
    ActiveSupport::JSON.decode(Base64.decode64(encoded_hash)) 
    rescue ActiveSupport::JSON::ParseError 
    ActiveSupport::JSON.decode(Base64.decode64(encoded_hash) + "}") 
    end 
end 

बचाव हिस्सा केवल एक '}' जोड़ने क्योंकि फेसबुक पर्याप्त अजीब यह डे इनकोडिंग हैश से बाहर कभी कभी यह बताने के लिए है (शायद वे तय यह पहले से ही ...)।

2
def decode64_url(str) 
    # add '=' padding 
    str = case str.length % 4 
    when 2 then str + '==' 
    when 3 then str + '=' 
    else 
     str 
    end 

    Base64.decode64(str.tr('-_', '+/')) 
end 
12

दिमित्री का जवाब सही है। यह '=' साइन पैडिंग के लिए खाता है जो स्ट्रिंग डीकोड से पहले होना चाहिए। मैं जेएसओएन विकृत हो रहा था और अंत में पता चला कि यह पैडिंग के कारण था। Read more about base64_url_decode for Facebook signed_request

यहाँ सरलीकृत विधि मैं प्रयोग किया जाता है:

def base64_url_decode(str) 
    str += '=' * (4 - str.length.modulo(4)) 
    Base64.decode64(str.tr('-_','+/')) 
end 
+0

मेरा मानना ​​है कि यह केवल 1 या 2 तक पैड के लिए कानूनी है, न कि 3 या 4। अगर str.lenght.modulo (4) शून्य है, तो पैड मत करो। http://en.wikipedia.org/wiki/Base64 –

+0

नोट: अगर आप सख्त_डेकोड 64 या urlsafe_decode64 का उपयोग करते हैं तो चार '=' के साथ पैडिंग तोड़ने लगता है, लेकिन decode64 द्वारा सहन किया जाता है। –

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