开发者

base 64 URL decode with Ruby/Rails?

I am working with the Facebook API and Ruby on Rails and I'm trying to parse the JSON that comes back. The problem I'm running into is that Facebook base64URL encodes their data. There is no built-in base64URL decode for Ruby.

For the difference between a base64 encoded and base64URL encoded, see wikipedia.

How do I decode 开发者_JAVA技巧this using Ruby/Rails?

Edit:

Because some people have difficulty reading - base64 URL is DIFFERENT than base64


Dmitry's answer is correct. It accounts for the '=' sign padding that must occur before string decode. I kept getting malformed JSON and finally discovered that it was due to the padding. Read more about base64_url_decode for Facebook signed_request.

Here's the simplified method I used:

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


Googling for "base64 for URL ruby" and choosing the first result lead me to the answer

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

The details of the cipher_token aren't important save that it can contain any byte values.

You could then, of course, make a helper to base64UrlDecode( data ).

What's happening is that it takes the encoded_token and replaces all the - and _ characters with + and /, respectively. Then, it decodes the base64-encoded data with unpack('m') and returns the first element in the returned array: Your decoded data.


For base64URL-encoded string s...

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


That's the way i parse the signed_request of my facebook application

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

The rescue part only add a '}', becouse facebook is weird enough to let it out of de encoded hash sometimes (maybe they fixed it already...).


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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜