Sign in with GitHub

Add "Sign in with GitHub" to an app: log users in, protect a route, and let them log out. The same steps work for any OAuth provider.

1. Register a GitHub OAuth app

In GitHub, go to Settings → Developer settings → OAuth Apps → New OAuth App. Set the Authorization callback URL to http://localhost:3000/auth/callback/github (use your real host in production). GitHub gives you a Client ID and a Client Secret.

2. Configure the server

Auth needs a store to keep users and sessions. Put the credentials in the environment:

GITHUB_ID=your-client-id
GITHUB_SECRET=your-client-secret
SECRET=a-long-random-string   # signs the session cookie
import server from '@server/next';
import kv from 'polystore';

export default server({
  store: kv(new Map()),   // use Redis in production
  auth: 'cookie:github',
})
  .get('/', (ctx) =>
    ctx.user
      ? `Hi ${ctx.user.name}`
      : '<a href="/auth/login/github">Sign in with GitHub</a>',
  );

Open the page and click the link: the OAuth flow runs and you come back signed in.

3. Protect a route

The signed-in user is on ctx.user on every request (undefined when logged out), so a one-line middleware guards a route:

const requireUser = (ctx) => {
  if (!ctx.user) return 401;
};

export default server({ store, auth: 'cookie:github' })
  .get('/account', requireUser, (ctx) => `Your email: ${ctx.user.email}`);

4. Log out

POST /auth/logout clears the session:

<form method="POST" action="/auth/logout">
  <button>Log out</button>
</form>

Next steps

  • Swap the in-memory Map for a persistent store.
  • Add more providers with the object form: auth: { strategy: 'cookie', providers: ['github', 'google'] }. See Authentication.