64-разрядный URL-адрес с Ruby/Rails?

Я работаю с API Facebook и Ruby on Rails, и я пытаюсь разобрать JSON, который возвращается. Проблема, с которой я сталкиваюсь, заключается в том, что Facebook base64URL кодирует свои данные. Для Ruby нет встроенного декодера base64URL.

За разницу между закодированным base64 и base64URL, см. wikipedia.

Как декодировать это с помощью Ruby/Rails?

Edit

Поскольку некоторые люди испытывают трудности с чтением - URL-адрес base64 отличается от base64

Ответ 1

Googling для "base64 для URL ruby" и выбора первого результата приведет меня к ответ

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

Детали cipher_token не являются важно сохранить, что он может содержать любые байтов.

Тогда вы могли бы сделать помощником base64UrlDecode( data ).

Что происходит, так это то, что он принимает encoded_token и заменяет все символы - и _ + и / соответственно. Затем он декодирует данные с кодировкой base64 с помощью unpack('m') и возвращает первый элемент в возвращаемом массиве: ваши декодированные данные.

Ответ 2

Ответ Дмитрия правильный. Он учитывает заполнение знака '=', которое должно произойти до декодирования строки. Я продолжал получать неправильный JSON и, наконец, обнаружил, что это произошло из-за прокладки. Узнайте больше о base64_url_decode для Facebook signed_request.

Здесь используется упрощенный метод:

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

Ответ 3

Для base64URL-кодированной строки s...

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

Ответ 4

То, как я разбираю подписанный_запись моего приложения facebook

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

Спасательная часть только добавляет '}', потому что facebook достаточно странно, чтобы иногда исключать его из кодированного хэша (возможно, они уже исправили его...).

Ответ 5

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