Tuesday, October 20, 2015

GitHub Auth Basics | Using Sinatra (RubyGem) | Installing Ruby - Part 2

Fam,

Ok, so I struggled yesterday with trying to get my simple Ruby application running in Sinatra locally according to GitHub's Authentication tutorial. See my struggle here on Part 1.

So, I had to start over and ensure my understanding of what was happening on my machine. This happened earlier today with reinstalling Ruby and Sinatra. See my victory and coding pleasure here. Lots of thanks to those who created the RubyInstaller project and gave great instructions on their GitHub wiki.

Now, I'm going to see how to continue my path with the GitHub Authentication tutorial.

I want to see if my Ruby application works now if I run "server.rb". This file is in my directory located at "C:\Users\[me]\RubyProjects\github-auth". I have a subfolder in here as well named "views" which contains the file "index.erb".



Code for "server.rb":
require 'sinatra'
require 'rest-client'
require 'json'

CLIENT_ID = ENV['GH_BASIC_CLIENT_ID']
CLIENT_SECRET = ENV['GH_BASIC_SECRET_ID']

get '/' do
  erb :index, :locals => {:client_id => CLIENT_ID}
end

Code for "index.erb":
<html>
  <head>
  </head>
  <body>
    <p>
      Well, hello there!
    </p>
    <p>
      We're going to now talk to the GitHub API. Ready?
      <a href="https://github.com/login/oauth/authorize?scope=user:email&client_id=<%= client_id %>">Click here</a> to begin!</a>
    </p>
    <p>
      If that link doesn't work, remember to provide your own <a href="/v3/oauth/#web-application-flow">Client ID</a>!
    </p>
  </body>
</html>

Installing the Gems

First, I know I need to ensure I have the libraries installed via "gem" considering they're called out in my "server.rb" file. Here are the libraries (or gems) that I'm talking about:
  • sinatra
  • rest-client
  • json
Here are the commands I enter in the Windows Command Prompt (but I'm skipping sinatra and json because I already installed these from previous blogs above):
> gem install sinatra --platform=ruby
> gem install json --platform=ruby
> gem install rest-client --platform=ruby

Here's the result:



Wow! No issue at all. Again, notice we're installing all the gems on Windows via Command Prompt (avoiding Cygwin).

Ok, let's go to the directory with the "server.rb" file and run it via Command Prompt. Oh no, I'm getting an error.


Troubleshooting a Gem (rest-client)

From searching for solutions on the Internet, I realized from this SO question (http://stackoverflow.com/questions/7964778/no-such-file-to-load-ffi-c-loaderror) that I might not have the library (gem) installed called "ffi". So, I run the following command:

>gem install ffi --platform=ruby


Yes, this resolved my issue!


Now we are becoming troubleshooting experts with Ruby while learning this Basic Authentication in GitHub - woohoo! Finally making progress.

GitHub Basic Authentication - Coding Foward

Now that our Sinatra application works, let's click on the "Click here" and see if we can continue to follow GitHub's instructions.


Since I didn't sign in yet, GitHub has a nice security setting that ensures I'm logged in before proceeding. I add in my credentials and sign in.


Yes, finally we are making progress with the GitHub Basic Authentication tutorial. The nice thing here is that we already added our GitHub Client ID and Client Secret into our GitHub stored application and as environment variables on my local machine. So when we did click on the link "Click here", the Sinatra server executed the code and automatically connected everything (values and online connection).

Now we need to continue with instructions from section "Providing a Callback".

Providing a Callback

I update my file "server.rb" according to the GitHub instructions and now my code looks like this:

require 'sinatra'
require 'json'
require 'rest-client'

CLIENT_ID = ENV['GH_BASIC_CLIENT_ID']
CLIENT_SECRET = ENV['GH_BASIC_SECRET_ID']

get '/' do
  erb :index, :locals => {:client_id => CLIENT_ID}
end

get '/callback' do
  # get temporary GitHub code...
  session_code = request.env['rack.request.query_hash']['code']
  
  # ... and POST it back to GitHub
  result = RestClient.post('https://github.com/login/oauth/access_token',
                      {:client_id => CLIENT_ID,
                       :client_secret => CLIENT_SECRET,
                       :code => session_code
                      },
                      :accept => :json)
  
  # extract the token and granted scopes
  access_token = JSON.parse(result)['access_token']
end

I restart my Sinatra (local ruby server) and re-run the "server.rb" file in order for the new code to take effect. In case, we forgot - Ctrl+C, then >ruby server.rb.

Excellent! We received a token from GitHub's API Authentication.
332bc61cc3579befef5cac7d9003350c51c7a870


Checking Granted Scopes

I now attempt the next section and add the code for checking the user scope. Strange. I get another error (to troubleshoot).


I had to update the code so I could understand it more (see final code below in screenshots). This took me some time to troubleshoot because I had to learn Ruby code to troubleshoot. =p Once fixed, this is the resulting screen:


Yep, a blank screen.

Making Authenticated Requests

Now that we have the scope granted for my user, let's access my private email. Notice, I check my email settings to be certain of my settings. I check in my personal settings and in my application's settings. I don't care about the generated tokens because my code will generate one based on my client ID and Secret related to my application called "basics-of-authentication".



So, I should be able to access my email address once my access is authenticated. I add in the code per GitHub's tutorial. Ugh, another error.


GitHub's authentication is so irritating. I'm running into another issue but this time related to my user authentication (user permissions because I'm able to get my user scope). Here's another way I tried checking (by pasting the line of code directly into the browser but without my token).


They're similar messages. So, my token must not be the issue. After quite a lot of troubleshooting, I finally updated the code (to by-pass getting the authenticated user information and instead getting user's public information). Notice this JSON results parses into a Hash Map.

Then, I get the emails and add into the Hash Map at key 'private emails'. Finally, pass the authenticated results as variable locals to the basic.erb file. This smooth flow finally displays the following screen.


Victory at last!

Here's an update that might be useful to know and I'm keeping for my records. :)
https://developer.github.com/changes/2014-04-08-reset-api-tokens/

My Code:  server.rb




Enjoy!

No comments:

Post a Comment