Skip to content

Sign in with GitHub

Your users can sign in with their GitHub account instead of choosing a name and seed phrase. Each user gets their own key, the same one every time they sign in, on any device.

  • Nothing to set up. You don't register anything with GitHub or with PrefsDB. There's no client ID and no secret.
  • Nothing to remember or lose. There's no seed phrase; signing in again finds the same data.
  • One line of code. PrefsDB.signInWithGitHub() does the whole sign-in.

The difference from Sign in with Google and Sign in with Microsoft: GitHub's sign-in screen shows PrefsDB as the app asking, not your app, because PrefsDB signs the user in on your behalf. GitHub only shares the user's public profile with PrefsDB, and asks for no other permissions.

Ready-made buttons

Sign-in Buttons adds this provider's button, and any of the others, to your page with a few lines, and handles the popup for you. GitHub needs no setup.

How it works

  1. The user clicks your "Sign in with GitHub" button, and your page calls PrefsDB.signInWithGitHub().
  2. A small window opens on GitHub's sign-in screen. The user signs in, or, if they've used it before, the window closes almost at once.
  3. The window hands your page a one-time code, which only your page can use, and PrefsDB gives you the user's key.

From there it's an ordinary PrefsDB object.

Add sign-in to your page

Your page must be served over https, or from http://localhost while you develop.

<script src="https://prefsdb.com/prefsdb.v1.min.js"></script>

<button id="signin">Sign in with GitHub</button>

<script>
document.getElementById("signin").addEventListener("click", async () => {
  try {
    const db = await PrefsDB.signInWithGitHub({ name: "settings" });
    await db.key("theme").write("dark");
    console.log(await db.key("theme").read());
  } catch (err) {
    console.error("Sign-in failed:", err.error, err.message);
  }
});
</script>
# Sign-in with GitHub happens in a browser window, so there's no way
# to do it with curl alone. After signing in, your page trades the
# one-time code it receives for the key (in the request body, never
# the URL), from the page's own address:
curl -s -c cookies.txt https://prefsdb.com/api/v1/getkey/ \
  -H "Origin: https://app.example.com" \
  --data-urlencode "provider=github" \
  --data-urlencode "signin_code=$CODE" \
  --data-urlencode "code_verifier=$VERIFIER" \
  --data-urlencode "name=settings"

A few things to know:

  • Call it straight from a click. Browsers only allow a new window right after a click. signInWithGitHub() opens it first thing, so call it directly in your click handler, before anything else that waits.
  • name picks one of several keys for the same user, as with getkey(). Leave it out and it's "default".
  • The same options as getkey() work here too: offline, offlineTtl, sessionTtl, optimistic, encryption and throwOnError. namespace and appcred don't apply.
  • To change the key itself, call db.rotate() with no arguments.
  • If your site sets a Cross-Origin-Opener-Policy header, use same-origin-allow-popups, not same-origin. With same-origin the sign-in window can't reach your page.

Signing out

When your user signs out, call await db.logout(). It deletes what the key kept in this browser (cached values and changes not sent yet), so the next person on a shared computer can't see them. Then forget your db object. With the sign-in buttons, call signin.signOut() instead, which does the same. See Signing out.

Which users get which key

A key belongs to one GitHub account on your site (the address your page is served from, such as https://app.example.com) and the name you pass. Another site gives the same person a different key. A second address for your app, like a staging site, also gets its own keys.

Email address

PrefsDB doesn't ask GitHub for the user's email address, so it doesn't keep one for these keys. That doesn't stop anything working: the key works right away, with no email step.

Letting users see their data

db.reviewUrl() is a page where your users sign in with GitHub again to see their data, download it all, or upgrade their storage. It shows PrefsDB's name, like the sign-in itself, and it also works if your app is no longer around.

Storage

A signed-in user's free storage is shared across every site they use with PrefsDB through the same GitHub account. See Storage space, and use db.onStorage() to warn users before they run out.

Encrypting data in the browser

Client-side encryption works with signed-in users too, but it still needs its own key or passphrase. Don't make one from anything about the GitHub account, such as the user's name or ID: PrefsDB sees those, so data encrypted with them wouldn't be private from PrefsDB.

If something goes wrong

What you see What to do
POPUP_BLOCKED The browser blocked the sign-in window. Call signInWithGitHub() directly from a click.
POPUP_CLOSED The user closed the window before signing in.
GITHUB_SIGNIN_CANCELLED The user chose not to sign in on GitHub's screen.
GITHUB_SIGNIN_FAILED GitHub didn't answer as expected. Try again shortly.
IDTOKEN_INVALID The sign-in couldn't be checked, or it was too old. Ask the user to sign in again.
IDTOKEN_REPLAYED That sign-in was already used. Sign in again.

More in Error Codes.