Skip to content

typeclasses/login-with-github-ts

Repository files navigation

login-with-github

This package provides the basic primitives for using GitHub OAuth. It is not a complete turnkey solution, but gets you halfway toward writing one.

Prerequisites

OAuth credentials from https://github.com/organizations/<org>/settings/apps/<app>.

const client = {
    id: "...",
    secret: "...",
}

Settings for your CSRF state cookie.

const cookie = {
    domain: "example.com"
    path: "/",
    name: "...", // Whatever you like
}

A function for generating CSRF state secrets.

function newSecret() {
    const buffer = Buffer.alloc(16);
    crypto.getRandomValues(buffer);
    return buffer.toString("hex");
}

Value of the User-Agent header for requests you generate; GitHub requires this and recommends it include your GitHub user/organization and repository name.

const userAgent = "@your-org/your-repo"

You can now construct a LoginWithGitHub instance.

loginWithGitHub = new LoginWithGitHub({
    client, cookie, newSecret, userAgent
})

Redirect to GitHub

Your server will need two routes. The first initiates the OAuth process when a user indicates that they want to log in with GitHub. Use redirectToOAuth to create a Response which redirects to GitHub.

const response = loginWithGitHub.redirectToOAuth()

The OAuth flow is now out of your hands until the user is logged into GitHub and has authorized your application. Once that happens, GitHub will redirect the user back to your application, and the callback URL you have specified in your GitHub app settings.

OAuth callback

Your OAuth callback route must be a GET operation that does several things.

First, a few checks:

  • If there is an error query parameter, display the error and do nothing else; OAuth has failed.

  • Verify that the state query parameter matches the state cookie (whose name you specified in the LoginWithGitHub configuration). If not, do nothing else; OAuth has failed.

Let code be the value of the code query parameter, and call getAccessToken to use the code to obtain an access token from GitHub.

const accessTokenResponse =
    await loginWithGitHub.getAccessToken({ code })

If accessTokenResponse.success, you can now have an access token that can be used to perform GitHub API actions on the user's behalf. What operations you can perform depends on the scopes requested (see the GitHub app settings).

const { accessToken } = accessTokenResponse

At minimum, you will be able to see some information about the authenticated user. This package does not provide a full GitHub API client, but it does offer one operation most pertinent to a "login with GitHub" feature.

const userResponse =
    await loginWithGitHub.getUser({ accessToken })

If userResponse.success, you have successfully obtained a verified GitHub user ID.

const { userId } = userResponse

About

basic primitives for using GitHub OAuth

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published