Contract Work

Wednesday, September 25, 2013

Environment Variable, Bash, and the omniauth-twitter gem, Oh My.

I just started building a new application and decided that I'd like people to sign in via Facebook or Twitter which meant installing the omniauth-twitter gem (and the omniauth-facebook gem but I'm not quite there yet).

My first challenge was to figure out how to keep my secret token a secret. Everyone says you never commit your secret stuff into Github, which makes sense but I didn't know how else to do it. In order to keep the tokens a secret, you need to store them as environment variables on your computer so that they can be called by the application when it is running. I stored my twitter_key; and twitter_secret as environment variable in ~ /.bashrc. Which led to an error of uninitialized omniauth and a timeout. I then learned that environment variables need to be uppercase so I re-saved them as TWITTER_KEY and TWITTER_SECRET (Thanks to Betsy for help on this one). This is what it looks like:

export TWITTER_KEY=your_key_goes_here
export TWITTER_SECRET=your_secret_goes_here

Then I got a different error. When I clicked, "Sign in with Twitter" the /auth/twitter path lead to a 401 oauth::unauthorized. Looking at the trace, the last errors had to do with requesting and receiving the tokens. I tried to see if the key showed up by calling

$ echo $TWITTER_KEY 

in the terminal and at first it did return, but when I ran the rails console and tried

ENV['TWITTER_KEY'] 


which should have yielded the same result, I got nil. I also tried utilizing the pry gem to check if the variables were being sourced from my initializer like this:

OmniAuth.config.logger = Rails.logger

Rails.application.config.middleware.use OmniAuth::Builder do
puts "key: #{ENV['TWITTER_KEY']}"
puts "secret: #{ENV['TWITTER_SECRET']}"
binding.pry

provider :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET']
end

and also got nil, and finally, I went back into the original window where I called $echo TWITTER_KEY tried again, and it wasn't working. So the issue was definitely that the tokens were not being read in the application.

The first solution (which was simple but turned out not to be the actual problem) was that I had been typing source ~/.bashrc into 1 terminal tab and then opening up my server in a different tab (talk about a hand-to-forehead moment but I didn't realize that the environments didn't copy over if you were in the same window but a different tab). When I did that, it worked. Clicking "Sign in with Twitter" lead to the appropriate /auth/twitter path where the user could approve the application. But again, that wasn't the route of the problem. The main issue was that I had to run the source code each time in order for the variable to be loaded into the system.

I tried to put the same export lines (the environment variables) as above into ~/.profile instead of in ~/.bashrc. I also put an echo line into ~/.profile:

echo "leading env, yay"

Putting an echo line will help see if things are set up correctly. If the shell is loading everything properly, when I open the shell or a new tab, I should see "loading env, yay" at the top.

But when I tried ~/.profile, nothing showed up. Then, I put the same echo line into ~/.bash_profile (thanks Chris for this suggestion!) and that worked! So things were working and set up correctly. To understand it a little better, Chris found this link from a great SuperUser answer. Basically, bash will only source ~/.bashrc or ~/.bash_profile. Bash looks, in order, for ~/.bash_profile, ~/.bash_login, or ~/.profile and sources whichever one it finds first. The solution is to alter the configuration.

At the top of ~/.bash_profile put:
Export BASH_CONF=”bash_profile”

At the top of ~/.bashrc put:
Export BASH_CONF=”bashrc”

Then in your terminal window type: $ echo $BASH_CONF and the file that shows up is the one being sourced.

And now my omniauth-twitter gem is working (well, at least the first part of the process is complete).



No comments:

Post a Comment