read

I've been a fan of Twitch since the Justin.tv days and always wanted to try and build something to tap into that audience. I had a little trouble setting up all the redirects correctly since Twitch is really strict about it, so I'm writing this blog post mostly as a reminder to my future self. Wouldn't be the first time I go back to my blog to solve an issue :)

First of all, you need to setup Devise and add the omniauth-twitch gem to your Gemfile. Devise's documentation is really good, so I'm not gonna cover that part.

In this case, Twitch is the only social network that you are allowed to login, so we are just gonna need to add a string uid column to the user table:

rails g migration add_uid_to_users uid:string
rake db:migrate

This will be needed to store the Twitch UID of the user for future logins. Now that we have this setup, we can move on to Devise configurations. Open your devise.rb initializer and add this to your config:

config.omniauth :twitch, ENV.fetch('TWITCH_CLIENT_ID'),
                           ENV.fetch('TWITCH_CLIENT_SECRET'),
                           redirect_uri: 
                           'APP_HOST/users/auth/twitch/callback'

In this example I'm using dotenv to store ENV variables, but feel free to use your preferred solution. You can obtain your Twitch keys from the connections page in your profile. The redirect_uri is usually what creates problems, since it's automatically generated by Devise. If you change your route names, remember to edit this accordingly.

We are now gonna create a new controller in controllers/users/omniauth_callbacks_controller.rb to support the redirect_uri we just set:

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def twitch
    @user = User.from_omniauth(request.env["omniauth.auth"])
    sign_in @user
    redirect_to home_index_path
  end

  def failure
    redirect_to root_path
  end
end

Now you just need to add it in the routes.rb file:

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

This will automatically generate the necessary endpoints for Twitch login thanks to Devise's magic. Add devise :omniauthable, :omniauth_providers => [:twitch] to your User model now and you'll be done with Devise configuration changes.

Last thing we need to do is defining the from_omniauth method we use in the controller. In this case I'm using a jsonb column called data to store all the info I get from the Omniauth callback. I might not need them now but they might be useful in the future, so it's good to store them safely.

def self.from_omniauth(auth)
    where(uid: auth.uid).first_or_create do |user|
      user.email = auth.info.email
      user.password = Devise.friendly_token[0,20]
      user.username = auth.info.nickname
      user.image_url = auth.info.image
      user.token = auth.credentials.token
      user.data['omniauth_info'] = auth
    end
  end

Setting a dummy password is just an added plus in case your Omniauth strategy breaks but you still want to give users the ability to login. After you've done this, you should be good to go! If you run into any problems, feel free to reach out to me @FanaHOVA or fana at alessiofanelli.com

Blog Logo

Alessio Fanelli

I'm a full stack developer with a love for sports.


Published

Image

Alessio Fanelli

Stay Sharp.

Back to Overview