DEV Community

Cover image for How to set your ENV and authorization with GitHub 🗝️
Margarita Potylitsyna
Margarita Potylitsyna

Posted on

How to set your ENV and authorization with GitHub 🗝️

Here is an ultimate working guide of how to implement authorization with GitHub and define necessary secret keys to development, CI/CD and deployment on Render.com for your Ruby on Rails App.
Before starting to work on this feature make sure you've already implemented Devise in your app and you have sign-in/sign-out user accounts. Always start with an issue and a new branch.

1. Add gems to your Gemfile:

gem "omniauth-github"
gem "omniauth-rails_csrf_protection"
gem "dotenv"
Enter fullscreen mode Exit fullscreen mode

Run bundle install.

2. In your config/initializers/devise.rb find this line of code:

# config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'
Enter fullscreen mode Exit fullscreen mode

Replace with this:

config.omniauth :github, ENV.fetch("MY_GITHUB_ID"), ENV.fetch("MY_GITHUB_SECRET"), scope: "user"
Enter fullscreen mode Exit fullscreen mode

I strongly recommend to avoid the GITHUB_ prefix for secret names because later you will run into troubles when you add secret keys to your GitHub repository. GitHub reserves this prefix for its internal use. That's why I start my names with MY_.

3. Register your app on GitHub here. Go to the “OAuth” tab and click on “Register a new application”.

Register your app on GitHub
On the next screen, fill in the “Application name”, the “Homepage URL” and the “Authorization callback URL”.

For now enter your live app preview’s URL (not your codespace’s):

https://<your-live-application-preview-url>
Enter fullscreen mode Exit fullscreen mode

in the “Homepage URL”, and:

https://<your-live-application-preview-url>/users/auth/github/callback
Enter fullscreen mode Exit fullscreen mode

in the “Authorization callback URL”.

If you're working locally enter the following:

http://localhost:3000/
http://localhost:3000/users/auth/github/callback
Enter fullscreen mode Exit fullscreen mode

On the next screen, you will see your Client ID, which is your first ENV "MY_GITHUB_ID". Also click to Generate a new client secret to get the second one for "MY_GITHUB_SECRET".

Register your app on GitHub

4. In the root of your app create .env and paste your secret keys:

MY_GITHUB_ID="<your-client-id>"
MY_GITHUB_SECRET="<your-client-secret>"
Enter fullscreen mode Exit fullscreen mode

There in the root I also recommend to create env_test.rb and paste the following code:

require "dotenv/load"

pp ENV.fetch("MY_GITHUB_ID")
pp ENV.fetch("MY_GITHUB_SECRET")
Enter fullscreen mode Exit fullscreen mode

Run ruby env_test.rb to make sure you set the keys correctly.

5. Now it's time to add new columns to your Users table.
Run migration:

rails generate migration AddOmniauthAndGithubAccessTokenToUsers
Enter fullscreen mode Exit fullscreen mode

Fill the new migration file in with:

class AddOmniauthAndGithubAccessTokenToUsers < ActiveRecord::Migration[7.1]
  def change
    add_column :users, :github_access_token, :string
    add_column :users, :provider, :string
    add_column :users, :uid, :string
  end
end
Enter fullscreen mode Exit fullscreen mode

Run rails db:migrate.

6. Add new route to your config/routes.rb:

Rails.application.routes.draw do

  devise_for :users, controllers: {
    omniauth_callbacks: "omniauth_callbacks",
  }

end
Enter fullscreen mode Exit fullscreen mode

7. Create new controller app/controllers/omniauth_callbacks_controller.rb and paste this code there:

class OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def github
    @user = User.from_omniauth(request.env["omniauth.auth"].except!(:extra))

    if @user.persisted?
      sign_in_and_redirect @user
      set_flash_message(:notice, :success, kind: "GitHub") if is_navigational_format?
    else
      session["devise.github_data"] = request.env["omniauth.auth"].except!(:extra)
      redirect_to root_url, alert: "Something went wrong."
    end
  end
end
Enter fullscreen mode Exit fullscreen mode

8. Add the following to your app/models/user.rb

  devise :omniauthable, omniauth_providers: %i[github]

  def self.from_omniauth(auth)
    find_or_create_by(provider: auth.provider, uid: auth.uid) do |user|
      user.email = auth.info.email
      user.password = Devise.friendly_token[0, 20]
      user.github_access_token = auth.credentials.token
    end
  end
end
Enter fullscreen mode Exit fullscreen mode

It's important to place self.from_omniauth(auth) method definition right after devise to avoid errors during authorization. devise also should be on the top of the code.

9. Navigate to /users/sign_in in your live app preview. Now you should have new nicely working button Sign in with GitHub.

/users/sign_in
It's time to make it look nice and add GitHub icon. If you've already generated views template for your Devise go to app/views/devise/shared/_links.html.erb
and replace this code:

<%- if devise_mapping.omniauthable? %>
  <%- resource_class.omniauth_providers.each do |provider| %>
    <%= button_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), data: { turbo: false } %><br />
  <% end %>
<% end %>
Enter fullscreen mode Exit fullscreen mode

With this:

<%- if devise_mapping.omniauthable? %>
  <%- resource_class.omniauth_providers.each do |provider| %>
    <div class="my-4" >
      <%= button_to omniauth_authorize_path(resource_name, provider),
              data: { turbo: false },
              class: "btn btn-secondary" do %>
        <i class="fa-brands fa-github pe-2"></i> Sign in with GitHub
      <% end %>
    <% end %>
  </div>
<% end %>
Enter fullscreen mode Exit fullscreen mode

If you don't have views for your Devise, generate it:

rails generate devise:views -b form_for
Enter fullscreen mode Exit fullscreen mode

and then replace the code as described above.

For the icon I use Font Awesome so don't forget to connect it to your app. Go to your app/views/layouts/application.html.erb and paste these lines of code into <head> or use partials if you'd like.
Also don't forget to connect Bootstrap itself.

<!-- Connect Font Awesome -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/js/all.min.js"></script>

<!-- Connect Bootstrap CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css">
Enter fullscreen mode Exit fullscreen mode

Feel free to change the color of the button using special Bootstrap classes. You can also adjust the space around the button by changing the class my-4 of <div>. Learn more about Bootstrap's margins and paddings.

Sign_in form
Also learn more about how to stylize the form itself using Bootstrap.

10. Since we store our secret keys securely in .env they won't be commited because this file listed in .gitignore. That's why we need to additionally define them for Render and GitHub itself in case you're using CI/CD pipelines. Let's start with Render. Navigate to Envinroment on Render.com and add your two keys there:

Render.com

Go back to your app settings on GitHub and replace Homepage URL and Authorization callback URL with your deployed domain name.

Register your app on GitHub

11. If you're using CI/CD go to your repository on Github, then Settings > Security > Secrets and variables > Actions. Add New Repository Secrets.
New Repository Secrets
In your app in .github/workflows/main.yml add the following:

MY_GITHUB_ID: ${{ secrets.MY_GITHUB_ID }}
MY_GITHUB_SECRET: ${{ secrets.MY_GITHUB_SECRET }}
Enter fullscreen mode Exit fullscreen mode

It should look like this:

main.yml

Now commit your changes and create Pull Request. Your test should succeed.

Test succeed

If so merge your branch to main. It will trigger the deployment. It also should go well.

That's it! Enjoy your authorization with GitHub! 🥷

Top comments (0)