Faraday: Setting Authentication Header in Rails results in NameError

Created on 25 Apr 2019  路  7Comments  路  Source: lostisland/faraday

Basic Info

  • Faraday Version: faraday (0.15.4)
  • Ruby Version: ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin17]
  • Rails Version: rails (5.2.3)

Issue description

I have issues with setting Authentication header in a Rails environment. It breaks with

uninitialized constant Faraday::Request::Authorization::KEY

Steps to reproduce

irb (good)

$ irb

2.5.1 :001 > require 'faraday'
 => true
2.5.1 :002 > conn = Faraday.new(url: "http://example.com") # create a new Connection with base URL
 => #<Faraday::Connection:0x00007feb7f059408 @parallel_manager=nil, @headers={"User-Agent"=>"Faraday v0.15.4"}, @params={}, @options=#<Faraday::RequestOptions (empty)>, @ssl=#<Faraday::SSLOptions (empty)>, @default_parallel_manager=nil, @builder=#<Faraday::RackBuilder:0x00007feb7f02bf58 @handlers=[Faraday::Request::UrlEncoded, Faraday::Adapter::NetHttp]>, @url_prefix=#<URI::HTTP http://example.com/>, @manual_proxy=false, @proxy=nil, @temp_proxy=nil>
2.5.1 :003 > conn.basic_auth("user", "pass")               # set the Authentication header
 => "Basic dXNlcjpwYXNz"
2.5.1 :004 > conn.get("/foo")
 => #<Faraday::Response:0x00007feb81104c98 @on_complete_callbacks=[], @env=#<Faraday::Env @method=:get @body="<!doctype html>\n<html>\n<head>\n    <title>Example Domain</title>\n\n    <meta charset=\"utf-8\" />\n    <meta http-equiv=\"Content-type\" content=\"text/html; charset=utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n    <style type=\"text/css\">\n    body {\n        background-color: #f0f0f2;\n        margin: 0;\n        padding: 0;\n        font-family: \"Open Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n        \n    }\n    div {\n        width: 600px;\n        margin: 5em auto;\n        padding: 50px;\n        background-color: #fff;\n        border-radius: 1em;\n    }\n    a:link, a:visited {\n        color: #38488f;\n        text-decoration: none;\n    }\n    @media (max-width: 700px) {\n        body {\n            background-color: #fff;\n        }\n        div {\n            width: auto;\n            margin: 0 auto;\n            border-radius: 0;\n            padding: 1em;\n        }\n    }\n    </style>    \n</head>\n\n<body>\n<div>\n    <h1>Example Domain</h1>\n    <p>This domain is established to be used for illustrative examples in documents. You may use this\n    domain in examples without prior coordination or asking for permission.</p>\n    <p><a href=\"http://www.iana.org/domains/example\">More information...</a></p>\n</div>\n</body>\n</html>\n" @url=#<URI::HTTP http://example.com/foo> @request=#<Faraday::RequestOptions (empty)> @request_headers={"User-Agent"=>"Faraday v0.15.4", "Authorization"=>"Basic dXNlcjpwYXNz"} @ssl=#<Faraday::SSLOptions (empty)> @response=#<Faraday::Response:0x00007feb81104c98 ...> @response_headers={"accept-ranges"=>"bytes", "cache-control"=>"max-age=604800", "content-type"=>"text/html; charset=UTF-8", "date"=>"Thu, 25 Apr 2019 08:54:40 GMT", "expires"=>"Thu, 02 May 2019 08:54:40 GMT", "last-modified"=>"Sat, 20 Apr 2019 01:36:22 GMT", "server"=>"ECS (dcb/7EA6)", "vary"=>"Accept-Encoding", "x-cache"=>"404-HIT", "content-length"=>"606", "connection"=>"close"} @status=404 @reason_phrase="Not Found">>

rails c (breaks)

$ rails c

Running via Spring preloader in process 41331
Loading development environment (Rails 5.2.3)
2.5.1 :001 > conn = Faraday.new(url: "http://example.com") # create a new Connection with base URL
 => #<Faraday::Connection:0x00007f8eb6f55590 @parallel_manager=nil, @headers={"User-Agent"=>"Faraday v0.15.4"}, @params={}, @options=#<Faraday::RequestOptions (empty)>, @ssl=#<Faraday::SSLOptions (empty)>, @default_parallel_manager=nil, @builder=#<Faraday::RackBuilder:0x00007f8eb6f54f50 @handlers=[Faraday::Request::UrlEncoded, Faraday::Adapter::NetHttp]>, @url_prefix=#<URI::HTTP http://example.com/>, @manual_proxy=false, @proxy=nil, @temp_proxy=nil>
2.5.1 :002 > conn.basic_auth("user", "pass")               # set the Authentication header
Traceback (most recent call last):
        1: from (irb):2
NameError (uninitialized constant Faraday::Request::Authorization::KEY)
2.5.1 :003 > conn.get("/foo")
 => #<Faraday::Response:0x00007f8ebd14ab10 @on_complete_callbacks=[], @env=#<Faraday::Env @method=:get @body="<!doctype html>\n<html>\n<head>\n    <title>Example Domain</title>\n\n    <meta charset=\"utf-8\" />\n    <meta http-equiv=\"Content-type\" content=\"text/html; charset=utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n    <style type=\"text/css\">\n    body {\n        background-color: #f0f0f2;\n        margin: 0;\n        padding: 0;\n        font-family: \"Open Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n        \n    }\n    div {\n        width: 600px;\n        margin: 5em auto;\n        padding: 50px;\n        background-color: #fff;\n        border-radius: 1em;\n    }\n    a:link, a:visited {\n        color: #38488f;\n        text-decoration: none;\n    }\n    @media (max-width: 700px) {\n        body {\n            background-color: #fff;\n        }\n        div {\n            width: auto;\n            margin: 0 auto;\n            border-radius: 0;\n            padding: 1em;\n        }\n    }\n    </style>    \n</head>\n\n<body>\n<div>\n    <h1>Example Domain</h1>\n    <p>This domain is established to be used for illustrative examples in documents. You may use this\n    domain in examples without prior coordination or asking for permission.</p>\n    <p><a href=\"http://www.iana.org/domains/example\">More information...</a></p>\n</div>\n</body>\n</html>\n" @url=#<URI::HTTP http://example.com/foo> @request=#<Faraday::RequestOptions (empty)> @request_headers={"User-Agent"=>"Faraday v0.15.4"} @ssl=#<Faraday::SSLOptions (empty)> @response=#<Faraday::Response:0x00007f8ebd14ab10 ...> @response_headers={"accept-ranges"=>"bytes", "cache-control"=>"max-age=604800", "content-type"=>"text/html; charset=UTF-8", "date"=>"Thu, 25 Apr 2019 08:50:58 GMT", "expires"=>"Thu, 02 May 2019 08:50:58 GMT", "last-modified"=>"Sat, 20 Apr 2019 01:36:22 GMT", "server"=>"ECS (dcb/7EA6)", "vary"=>"Accept-Encoding", "x-cache"=>"404-HIT", "content-length"=>"606", "connection"=>"close"} @status=404 @reason_phrase="Not Found">>

Gemfile.lock

  remote: https://rubygems.org/
  specs:
    actioncable (5.2.3)
      actionpack (= 5.2.3)
      nio4r (~> 2.0)
      websocket-driver (>= 0.6.1)
    actionmailer (5.2.3)
      actionpack (= 5.2.3)
      actionview (= 5.2.3)
      activejob (= 5.2.3)
      mail (~> 2.5, >= 2.5.4)
      rails-dom-testing (~> 2.0)
    actionpack (5.2.3)
      actionview (= 5.2.3)
      activesupport (= 5.2.3)
      rack (~> 2.0)
      rack-test (>= 0.6.3)
      rails-dom-testing (~> 2.0)
      rails-html-sanitizer (~> 1.0, >= 1.0.2)
    actionview (5.2.3)
      activesupport (= 5.2.3)
      builder (~> 3.1)
      erubi (~> 1.4)
      rails-dom-testing (~> 2.0)
      rails-html-sanitizer (~> 1.0, >= 1.0.3)
    activejob (5.2.3)
      activesupport (= 5.2.3)
      globalid (>= 0.3.6)
    activemodel (5.2.3)
      activesupport (= 5.2.3)
    activerecord (5.2.3)
      activemodel (= 5.2.3)
      activesupport (= 5.2.3)
      arel (>= 9.0)
    activestorage (5.2.3)
      actionpack (= 5.2.3)
      activerecord (= 5.2.3)
      marcel (~> 0.3.1)
    activesupport (5.2.3)
      concurrent-ruby (~> 1.0, >= 1.0.2)
      i18n (>= 0.7, < 2)
      minitest (~> 5.1)
      tzinfo (~> 1.1)
    addressable (2.6.0)
      public_suffix (>= 2.0.2, < 4.0)
    archive-zip (0.12.0)
      io-like (~> 0.3.0)
    arel (9.0.0)
    bindex (0.7.0)
    bootsnap (1.4.4)
      msgpack (~> 1.0)
    builder (3.2.3)
    byebug (11.0.1)
    capybara (3.18.0)
      addressable
      mini_mime (>= 0.1.3)
      nokogiri (~> 1.8)
      rack (>= 1.6.0)
      rack-test (>= 0.6.3)
      regexp_parser (~> 1.2)
      xpath (~> 3.2)
    carrierwave (1.3.1)
      activemodel (>= 4.0.0)
      activesupport (>= 4.0.0)
      mime-types (>= 1.16)
    childprocess (1.0.1)
      rake (< 13.0)
    chromedriver-helper (2.1.1)
      archive-zip (~> 0.10)
      nokogiri (~> 1.8)
    concurrent-ruby (1.1.5)
    connection_pool (2.2.2)
    crass (1.0.4)
    domain_name (0.5.20180417)
      unf (>= 0.0.5, < 1.0.0)
    dotenv (2.7.2)
    dotenv-rails (2.7.2)
      dotenv (= 2.7.2)
      railties (>= 3.2, < 6.1)
    erubi (1.8.0)
    excon (0.64.0)
    execjs (2.7.0)
    faraday (0.15.4)
      multipart-post (>= 1.2, < 3)
    ffi (1.10.0)
    fog-aws (3.4.0)
      fog-core (~> 2.1)
      fog-json (~> 1.1)
      fog-xml (~> 0.1)
      ipaddress (~> 0.8)
    fog-core (2.1.2)
      builder
      excon (~> 0.58)
      formatador (~> 0.2)
      mime-types
    fog-json (1.2.0)
      fog-core
      multi_json (~> 1.10)
    fog-xml (0.1.3)
      fog-core
      nokogiri (>= 1.5.11, < 2.0.0)
    formatador (0.2.5)
    fullcalendar-rails (3.9.0.0)
      jquery-rails (>= 4.0.5, < 5.0.0)
      jquery-ui-rails (>= 5.0.2)
      momentjs-rails (>= 2.9.0)
    fuzzy_match (2.1.0)
    globalid (0.4.2)
      activesupport (>= 4.2.0)
    http-cookie (1.0.3)
      domain_name (~> 0.5)
    i18n (1.6.0)
      concurrent-ruby (~> 1.0)
    i18n-js (3.2.1)
      i18n (>= 0.6.6)
    io-like (0.3.0)
    ipaddress (0.8.3)
    jbuilder (2.8.0)
      activesupport (>= 4.2.0)
      multi_json (>= 1.2)
    jquery-rails (4.3.3)
      rails-dom-testing (>= 1, < 3)
      railties (>= 4.2.0)
      thor (>= 0.14, < 2.0)
    jquery-ui-rails (6.0.1)
      railties (>= 3.2.16)
    kaminari (1.1.1)
      activesupport (>= 4.1.0)
      kaminari-actionview (= 1.1.1)
      kaminari-activerecord (= 1.1.1)
      kaminari-core (= 1.1.1)
    kaminari-actionview (1.1.1)
      actionview
      kaminari-core (= 1.1.1)
    kaminari-activerecord (1.1.1)
      activerecord
      kaminari-core (= 1.1.1)
    kaminari-core (1.1.1)
    listen (3.1.5)
      rb-fsevent (~> 0.9, >= 0.9.4)
      rb-inotify (~> 0.9, >= 0.9.7)
      ruby_dep (~> 1.2)
    loofah (2.2.3)
      crass (~> 1.0.2)
      nokogiri (>= 1.5.9)
    mail (2.7.1)
      mini_mime (>= 0.1.1)
    marcel (0.3.3)
      mimemagic (~> 0.3.2)
    mechanize (2.7.6)
      domain_name (~> 0.5, >= 0.5.1)
      http-cookie (~> 1.0)
      mime-types (>= 1.17.2)
      net-http-digest_auth (~> 1.1, >= 1.1.1)
      net-http-persistent (>= 2.5.2)
      nokogiri (~> 1.6)
      ntlm-http (~> 0.1, >= 0.1.1)
      webrobots (>= 0.0.9, < 0.2)
    method_source (0.9.2)
    mime-types (3.2.2)
      mime-types-data (~> 3.2015)
    mime-types-data (3.2019.0331)
    mimemagic (0.3.3)
    mini_magick (4.9.3)
    mini_mime (1.0.1)
    mini_portile2 (2.4.0)
    minitest (5.11.3)
    momentjs-rails (2.20.1)
      railties (>= 3.1)
    msgpack (1.2.10)
    multi_json (1.13.1)
    multipart-post (2.0.0)
    net-http-digest_auth (1.4.1)
    net-http-persistent (3.0.0)
      connection_pool (~> 2.2)
    nio4r (2.3.1)
    nokogiri (1.10.3)
      mini_portile2 (~> 2.4.0)
    normalize_country (0.2.2)
    ntlm-http (0.1.1)
    pg (1.1.4)
    public_suffix (3.0.3)
    puma (3.12.1)
    rack (2.0.7)
    rack-proxy (0.6.5)
      rack
    rack-test (1.1.0)
      rack (>= 1.0, < 3)
    rails (5.2.3)
      actioncable (= 5.2.3)
      actionmailer (= 5.2.3)
      actionpack (= 5.2.3)
      actionview (= 5.2.3)
      activejob (= 5.2.3)
      activemodel (= 5.2.3)
      activerecord (= 5.2.3)
      activestorage (= 5.2.3)
      activesupport (= 5.2.3)
      bundler (>= 1.3.0)
      railties (= 5.2.3)
      sprockets-rails (>= 2.0.0)
    rails-dom-testing (2.0.3)
      activesupport (>= 4.2.0)
      nokogiri (>= 1.6)
    rails-html-sanitizer (1.0.4)
      loofah (~> 2.2, >= 2.2.2)
    railties (5.2.3)
      actionpack (= 5.2.3)
      activesupport (= 5.2.3)
      method_source
      rake (>= 0.8.7)
      thor (>= 0.19.0, < 2.0)
    rake (12.3.2)
    rb-fsevent (0.10.3)
    rb-inotify (0.10.0)
      ffi (~> 1.0)
    rb-readline (0.5.5)
    regexp_parser (1.4.0)
    ruby_dep (1.5.0)
    rubyzip (1.2.2)
    sass (3.7.4)
      sass-listen (~> 4.0.0)
    sass-listen (4.0.0)
      rb-fsevent (~> 0.9, >= 0.9.4)
      rb-inotify (~> 0.9, >= 0.9.7)
    sass-rails (5.0.7)
      railties (>= 4.0.0, < 6)
      sass (~> 3.1)
      sprockets (>= 2.8, < 4.0)
      sprockets-rails (>= 2.0, < 4.0)
      tilt (>= 1.1, < 3)
    selenium-webdriver (3.142.0)
      childprocess (>= 0.5, < 2.0)
      rubyzip (~> 1.2, >= 1.2.2)
    spring (2.0.2)
      activesupport (>= 4.2)
    spring-watcher-listen (2.0.1)
      listen (>= 2.7, < 4.0)
      spring (>= 1.2, < 3.0)
    sprockets (3.7.2)
      concurrent-ruby (~> 1.0)
      rack (> 1, < 3)
    sprockets-rails (3.2.1)
      actionpack (>= 4.0)
      activesupport (>= 4.0)
      sprockets (>= 3.0.0)
    thor (0.20.3)
    thread_safe (0.3.6)
    tilt (2.0.9)
    tzinfo (1.2.5)
      thread_safe (~> 0.1)
    uglifier (4.1.20)
      execjs (>= 0.3.0, < 3)
    unf (0.1.4)
      unf_ext
    unf_ext (0.0.7.6)
    web-console (3.7.0)
      actionview (>= 5.0)
      activemodel (>= 5.0)
      bindex (>= 0.4.0)
      railties (>= 5.0)
    webpacker (4.0.2)
      activesupport (>= 4.2)
      rack-proxy (>= 0.6.1)
      railties (>= 4.2)
    webpacker-react (0.3.2)
      webpacker
    webrobots (0.1.2)
    websocket-driver (0.7.0)
      websocket-extensions (>= 0.1.0)
    websocket-extensions (0.1.3)
    xpath (3.2.0)
      nokogiri (~> 1.8)

PLATFORMS
  ruby

DEPENDENCIES
  bootsnap (>= 1.1.0)
  byebug
  capybara (>= 2.15, < 4.0)
  carrierwave (~> 1.0)
  chromedriver-helper
  dotenv-rails
  faraday
  fog-aws
  fullcalendar-rails
  fuzzy_match
  i18n-js
  jbuilder (~> 2.5)
  kaminari
  listen (>= 3.0.5, < 3.2)
  mechanize
  mini_magick
  momentjs-rails
  nokogiri
  normalize_country
  pg (>= 0.18, < 2.0)
  puma (~> 3.11)
  rails (~> 5.2.3)
  rb-readline
  sass-rails (~> 5.0)
  selenium-webdriver
  spring
  spring-watcher-listen (~> 2.0.0)
  tzinfo-data
  uglifier (>= 1.3.0)
  web-console (>= 3.3.0)
  webpacker
  webpacker-react

RUBY VERSION
   ruby 2.5.1p57

BUNDLED WITH
   2.0.1

Does anyone experience the same?

All 7 comments

Hi @JanOwiesniak, sorry to hear you're having issues with the basic_auth.
I've just setup a new Rails app based on Rails 5.2.3 and tried your script under the rails c:

$ bundle exec rails c

Running via Spring preloader in process 37544
Loading development environment (Rails 5.2.3)
2.5.1 :001 > conn = Faraday.new(url: "http://example.com")
=> #<Faraday::Connection:0x00007fa06a3fcf20 ...>
2.5.1 :002 > conn.basic_auth("user", "pass")
=> "Basic dXNlcjpwYXNz"

I was also on macOS and running ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin17] with faraday 0.15.4, so this should be exactly the same as your environment.

Since it worked with no issues on a pristine installation, I'd think this has something to do with your project setup, or your environment.
To exclude the latter, could you create a new rails app (rails new test_app), add faraday to the Gemfile and try your script in that app?

The constant that appears to be missing in your case is defined here, so I can only think there is some sort of conflict with another gem or with one of your initialisers where a constant named KEY is defined and then undefined somehow. This would cause faraday not to define it internally and cause that error later on

I can only think there is some sort of conflict with another gem or with one of your initialisers where a constant named KEY is defined and then undefined somehow. This would cause faraday not to define it internally and cause that error later on

Thank you so much for pointing this out. It had to do with my environment (a fresh rails project works as well). I defined a constant called KEY in the global namespace which is stupid.

I guess changing this line

KEY = 'Authorization' unless defined? KEY

into something like this (be more explicit about the KEY)

KEY = 'Authorization' unless defined? Faraday::Request::Authorization::KEY

could avoid those kind of pitfalls. WDYT?

Glad to hear that was the case!
Point taken, although if a constant named KEY was defined then Faraday should have used that one at runtime, unless undefined later on.
Nevertheless, I'm not really sure why we check if the constant to exist already (and without namespace, it will check all levels, including the global namespace).

I'd rename the variable into something more specific (e.g. BASIC_AUTH_KEY) and remove the check altogether, but first will run a quick search to see what's the rationale behind that line.

Thanks for raising this anyway 馃憤 !

UPDATE: everything was born from this and a Ruby 1.8.7 bug. We definitely don't need to check with defined? anymore 馃槃

Great News and thanks again for your help!

The defined? checks were added because of const reassignment warnings on rails app bootup from files being loaded multiple times. I would love to remove these checks altogether, and confidently set our constants the way we want. Maybe that could go out in a small gem pre-release so we can get some feedback on it.

Another fix would be changing the defined? checks to look at the ::Expanded::Module::Path. I'm going to list other cases in the code base that this is done, so we can make a single consistent fix:

This was fixed in #1122

Was this page helpful?
0 / 5 - 0 ratings

Related issues

yusefu picture yusefu  路  3Comments

aleksb86 picture aleksb86  路  3Comments

mokolabs picture mokolabs  路  3Comments

ioquatix picture ioquatix  路  4Comments

jedeleh picture jedeleh  路  3Comments