Search code examples
ruby-on-railsdeviseomniauth

Supporting both github.com and github enterprise in Devise logins?


I'm building a Rails application that normally authenticates against a local Github Enterprise installation when logging in users. I would like to enable logged-in users to associate their github.com ID to their account on my application, but struggle to figure out how to do this.

Specifically, the problem is that both authentication methods would use the github authentication strategy in the omniauth set up. However, the relevant OAUTH urls as well as my internal callback controller need to be different for each case (in one case, I actually want to do a login, in the other case, I simply want to add more information to the current_user). Unfortunately, as far as I can tell, I can only configure the github strategy once, but I need to set up two different configurations for the two different providers.

I have been searching through the Devise and Omniauth documentation for some time now, but without success. Am I barking up the wrong tree entirely here? If not, can somebody point me in the right direction, please?

Many thanks,

Steffen


Solution

  • After some digging in the devise sources, I found a reasonably straightforward solution. The central problem is how to get devise to use the same omniauth strategy twice, but with different API and callback URLs. So we need to register two instances of omniauth-github under two different provider IDs and names. To make this work, you need to explicitly give the strategy class name in the second instantiation. So, all together you get something like this:

    # Github Enterprise login through standard github provider
    config.omniauth :github,
                    Rails.configuration.ghe_oauth_id,
                    Rails.configuration.ghe_oauth_secret,
                    client_options: {
                      site: 'https://github-enterprise/api/v3',
                      authorize_url: 'https://github-enterprise/login/oauth/authorize',
                      token_url: 'https://github-enterprise/login/oauth/access_token'
                    },
                    scope: 'user repo'
    
    # Github.com support using the same strategy, but with a different provider ID and name
    config.omniauth :github_com,
                    Rails.configuration.github_com_oauth_id,
                    Rails.configuration.github_com_oauth_secret,
                    strategy_class: OmniAuth::Strategies::GitHub,
                    name: :github_com,
                    scope: 'user repo'
    

    The route setup remains the same as with a single omniauth provider. In my callbacks-controller for devise callbacks, I now have a method github for handling authentication through Github Enterprise and one github_com for github.com authentication.