Now that we have done some config, we can see that we are missing the API keys that will connect our app to GitHub. Unlike Google OAuth, Github is very easy to create.
You will see that you have a CLIENT ID but still need to generate a new secret key, so let's do it by clicking "Generate a new client secret".
Add keys to .env
Copy the Secret key and add it to your .env file along with the client ID:
# .env
# modify with your keys
GITHUB_ID=Ov23*********
GITHUB_SECRET=3cc73c***********************
Routes
Now that we have a good config, we'll need to activate new routes, and replace the existing devise_for :user by this line:
After adding the proper routes and controller action we will need to activate the Omniauth option from devise. In user.rb uncomment and add the following symbols to the devise options:
# models/user.rbclassUser<ApplicationRecord# Include default devise modules. Others available are:# :confirmable, :lockable, :timeoutable, :trackable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable, :omniauthable, omniauth_providers: [:github] # <- The new options# [...]end
We will also add the Omniauthable custom method:
# models/user.rbclassUser<ApplicationRecord# has_one_attached :avatar <- Uncomment If you want to attach a picture from github# [...]defself.from_omniauth(access_token) data = access_token.info user =User.where(email: data['email']).firstif user user.update(# Optional: You can create a migration for users to add GitHub username and name to the user instance.# github_username: data['nickname'], # name: data['name'], email: data['email'] )else user =User.create(# Optional: You can create a migration for users to add GitHub username and name to the user instance.# github_username: data['nickname'],# name: data['name'], email: data['email'], password: Devise.friendly_token[0,20] )end# Optional: Uncomment for adding avatar image from github, make sure you have a cloudinary API_KEY in your .env# user.avatar.purge if user.avatar.attached?# user.avatar.attach(io: URI.open(data['image']), filename: 'avatar.jpg', content_type: 'image/jpg') userendend
Views
Let's add the GitHub signup to the sessions/new file. I like to add it to the login instead of the signup as to not lose the before_action :authenticate_user! auto-redirect function. As our code either updates or creates. You can now ignore the signup page and unlink it from all the buttons on your page.
#app/views/sessions/new.html.erb# [...] # Add this code where you want the GitHub sign in button<%- if devise_mapping.omniauthable? %> <%- resource_class.omniauth_providers.each do|provider| %> <%= button_to omniauth_authorize_path(resource_name, provider), data: { turbo: false }, class: "btn btn-primary mt-12"do %> <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 opacity-70" viewBox="0 0 24 24"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
Sign in with Github<br /> <% end %> <smallclass="text-xs text-gray-500">Your Github Username to receive an automatic invite to LightningRails repo.</small> <% end %><% end %># [...]
In Production
To have this code work on production as well as on development, you will need to create a second Github app and follow these steps again:
Now you should have two GitHub apps. One for development and one for production.
The only step left will be to add the production ID and key to Heroku from your terminal:
(replace the API key by your actual production API key and ID)
heroku config:set GITHUB_SECRET=YOUR_API_KEY
And
heroku config:set GITHUB_ID=YOUR_GITHUB_ID
Et voila! You have a brand-new GitHub authentication setup.
Your techy users will thank you! 🙏
Common Errors 🐞:
Omniauthable is undefined: Did you restart your server after installing the Omniauthable Gem? If not do it an it should get fixed.
Must supply API_KEY: Are you adding avatars without a Cloudinary key in your .env file? That's probably the cause, head to Cloudinary, and add your API key in the .env file.