Github oauth login - dev vs prod "authorization callback URL" - how do I solve this situation?


#1
  1. I want github oauth to be the only way a user can login to my app

  2. I have a pre-selected list of github account names that each login attempt will be validated against.

  3. I set up an “authorization callback URL” in the github oauth application settings for my app.

My problem is that when I run my app in local development mode, I cannot login with github because the “authorization callback URL” is configured for my production environment.

If I change it through my github setting page and set the “authorization callback URL” to localhost:3000, then it works in development mode but stops working in production.

I want to be able to login seamlessly using github oauth from either my dev environment or my prod environment - how can I arrange this?

Thanks.


#2

Hey jononomo,

Typically, if you’re using API keys, you want to have two separate keys - one for production, and one for development. When using the Github API for OAuth, I will normally create two Github projects so that I have access to two different keys.

For example, I’ll create a my-website-dev project and my-website project on Github. Then in my Meteor settings.json file, I’ll have access to something like:

    "public" : {
        "github": {
              "id": xxxxxxxxxxxxx
        }
    },
     "private": {
        "github": {
              "secret": xxxxxxxxxxxx
        }     
    }
}```

Here, you can place your production application's keys, and you can setup a `settings-dev.json` to hold your dev keys. Then on Github, you can have your production callback URLs point to your actual domain, and the my-website-dev callback URLs point to your localhost for development.

It takes an extra step in configuration, but in your code, you'll only have to point at `Meteor.settings.private.github.secret`, when referencing your OAuth creds.

When you have both `settings.json` and `settings-dev.json` you can simply run `meteor --settings settings-dev.json` for development and just `meteor` or `meteor run` for production.

Hope this helps!

#3

Hi Anichale,

Thanks very much for your response. Setting up two github apps - one for dev, one for prod - sounds like the right thing to do.

However, my setup is different from yours – I do not have the github client id and secret stored in a settings.json file – rather, they are in a DB collection called meteor_accounts_loginServiceConfiguration that contains only one record that looks like this:

{
  "_id": "QtiK82eKjLTeASXT6",
  "service": "github",
  "clientId": "156d175xxxxxxx289052",
  "secret": "0060acd74ae8bd589xxxxxxxx80c4c3a6a08ceec",
  "loginStyle": "popup"
}

A couple questions: first, how did this info get into the database in the first place? Second, how do I add a second client id and secret for the same github service?

Thanks much.


#4

If you’re using Meteor’s OAuth services, they will create these documents for you. However, they give you an option to configure the services through ServiceConfiguration which should be done in a Meteor.startup method on the server.

Essentially, you can configure the way Meteor calls the OAuth like so:

const github = Meteor.settings.private.OAuth.github;

export const configureOAuth = () => {
  // if settings initialized
  if (github) {
    ServiceConfiguration.configurations.upsert({ service: 'github' }, {
      $set: {
        clientId: github.clientId,
        loginStyle: 'popup',
        requestOfflineToken: false,
        secret: github.secret
      }
    });
  }
};

and then in your server startup file:

import { configureOAuth } from './oauth.js';

Meteor.startup(() => {
  configureOAuth();

  /**
   * Other startup stuff here...
   */
})

Now you should be able to switch keys from just your settings files.

See this meteorchef tutorial for further explanation.


#5

Thanks much, Anichale. I’m trying to follow this example but am wondering whether it depends on my dev environment and production environment using different databases. In my case, I use only one database for both production and development. From looking at the code you posted, it appears that staring my app in dev mode will update the client ID and secret for production, and vice versa. Am I overlooking something?

Thanks.


#6

Hey jononomo,

I recommend not to use the same database for both production and dev. We typically hold a fresh mongodump of the latest database on our local machines while developing, so we have the latest data, but are not messing around with anything that might compromise production data.

But, if that is not feasible right now, you should still be able to switch between keys as the settings should change each time you restart your server. AFAIK, it should add a new meteor_accounts_loginServiceConfiguration object when you change the configuration.

Cheers


#7

Yes, I think you are correct. Thanks very much.


#8

More discussion on this topic here: Can I force a DB update to be synchronous?