Guide to using OAuth 2.0 to access GitHub API

Tony
6 min readSep 7, 2023

--

Authenticating with the GitHub API can enable your web application to manage repositories, CI/CD pipelines and much more on behalf of your users. In this article, I demonstrate how you can set up your application to authenticate with the GitHub API using OAuth 2.0; many examples shown will be in the context of setting up an integration between Infisical and GitHub but you should be able to adapt them to your own use-case.

At a high-level, we’ll need to configure an OAuth application in GitHub and set up the OAuth 2.0 flow in our application to work with it.

Not sure what OAuth is? Check out the primer here.

The high-level overview

Before we dive into how we can implement OAuth 2.0 with GitHub to access the GitHub API, it is helpful to understand the high-level flow that we’ll be dealing with.

OAuth 2.0 with GitHub
  • (A) Redirect the user from the browser to GitHub: The user presses a button in the browser and gets redirected to GitHub where they can grant the application access to their GitHub account.
  • (B) Return the user from GitHub back to the browser: After the grant, the user is redirected back to the browser with a code .
  • (C) Perform the code-token exchange: Send the code from the browser to the server to be exchanged with GitHub. After the exchange, we should receive an access_token back back from GitHub.
  • (D) Use the access token to make requests against the GitHub API: With the access_token , we can now make requests to the GitHub API on behalf of the user.

Cool beans — We’re now ready to implement OAuth 2.0 with GitHub to access the GitHub API.

Configuring an OAuth application in GitHub

  1. Create an account with GitHub here: https://github.com
  2. Start by navigating to your user Settings > Developer settings > OAuth Apps to create a new GitHub OAuth application.

Note that, if you have a GitHub organization, you can create an OAuth application under it in your organization Settings > Developer settings > OAuth Apps > New Org OAuth App.

3. Create the OAuth application.

As part of the form, set the Homepage URL to your self-hosted domain https://your-domain.com and the Authorization callback URL to https://your-domain.com/integrations/github/oauth2/callback ; you can of course pick your own redirect URL based on your desired routing structure. This is the URL that GitHub will redirect the user back to after they have authorized the application to access their GitHub account.

4. Obtain the Client ID and generate a new Client Secret for your GitHub OAuth application; keep these handy.

Configuring your web application to work with the GitHub OAuth application

5. Redirect the user to GitHub from your web application frontend.

In your web application frontend, create a button that, when pressed, initiates the OAuth 2.0 flow by redirecting users to GitHub, so they can log in and grant the web application access to their GitHub account. The button handler should contain the following logic:

// the client id from github
const client_id = ""

// create a CSRF token and store it locally
const state = crypto.randomBytes(16).toString("hex");
localStorage.setItem("latestCSRFToken", state);

// redirect the user to github
const link = `https://github.com/login/oauth/authorize?client_id=${client_id}&response_type=code&scope=repo&redirect_uri=${window.location.origin}/integrations/github/oauth2/callback&state=${state}`;
window.location.assign(link);

Here, we generate a CSRF token to be stored in local storage and sent along as the state parameter to GitHub; this has to do with mitigating Cross-Site Request Forgery (CSRF) attack which is beyond the scope of this article.

Note that you should replace the redirect_uri in link with the one that you registered in step 2 in GitHub. When users press the button, they should be redirected to GitHub as shown below:

6. Validate the state parameter upon the user being redirected back to the web application and send code to the backend.

Since GitHub will redirect the user back to redirect_uri after they have logged in and granted the web application access to their GitHub account, you need to make a page for it to handle the next part of the OAuth 2.0 flow. Here, the redirect_uri will come with a code and state parameter; you should parse these parameters off the URL and validate that the state parameter matches the CSRF token in local storage from step 4. If it’s good, you can proceed to send the code to the web application backend to perform the code-token exchange.

const { code, state } = queryString.parse(router.asPath.split("?")[1]);

// validate the state parameter
if (state !== localStorage.getItem("latestCSRFToken") {
localStorage.removeItem("latestCSRFToken");
// send the code to the backend
const res = await axios.post("/api/oauth-token", {
code
});
}

7. Exchange the code for an access_token .

In your application backend, you should now perform a code-token exchange with the GitHub API endpoint for it.

const res = await axios.get(
"https://github.com/login/oauth/access_token",
{
params: {
client_id: process.env.GITHUB_CLIENT_ID,
client_secret: process.env.GITHUB_CLIENT_SECRET,
code: code,
redirect_uri: `your-domain/integrations/github/oauth2/callback`,
},
headers: {
"Accept": "application/json",
"Accept-Encoding": "application/json",
},
}
);

const access_token = res.data.access_token;

8. Use the access_token to access the GitHub API on behalf of the user.

You can now access the GitHub API on behalf of the user by including the access_token in requests made to the API.

That’s it!

You now know how to set up your application to authenticate with GitHub APIs using OAuth.

Tips

Implementing OAuth 2.0 correctly is critical for your application and user security.

Here’s some practical advice that you should keep in mind:

  • Don’t hardcode the Client ID and Client Secret for your application anywhere in your codebase. Instead, you should store both the Client ID and Client Secret for your application securely, preferably as application environment variables. Even better, you should consider storing these credentials in a secret manager like Infisical and fetch them back to the backend at runtime.
  • Don’t perform the OAuth code-token exchange multiple times. The exchange should be performed once after which you should manage access tokens to make all subsequent requests to the service API. Since these tokens should be dealt with securely, as with my previous tip, you should consider storing them in a secret manager as well.

— -

Infisical — The open source secret management platform

Infisical (9.7K+ ⭐️)helps thousands of teams and organizations store and sync secrets across their team and infrastructure.

GitHub repo: https://github.com/Infisical/infisical

--

--