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