Civic Docs
Civic Auth
Civic Auth
  • 🔏Civic Auth
  • Integration
    • React
    • Next.JS
    • Node.JS
      • Express
      • Hono
      • Fastify
    • Other OIDC / OAuth 2.0-Compliant Environments
    • FAQs
    • Error Codes
    • Bring Your App to Production
  • Web3
    • Embedded Wallets
    • Ethereum / EVM
    • Solana
Powered by GitBook
On this page
  • 1. Install dependencies
  • 2. Configure your App
  • 3. Set up Cookies
  • 4. Create a Login Endpoint
  • 5. Create the Callback Endpoint
  • 6. Create a Logout Endpoint
  • 7. Add Middleware
  • 8. Use the Session
  • PKCE and Client Secrets

Was this helpful?

  1. Integration
  2. Node.JS

Hono

PreviousExpressNextFastify

Last updated 2 months ago

Was this helpful?

Follow these simple steps to set up Civic Auth with a backend (a working example is available in our ).

1. Install dependencies

npm install @civic/auth
yarn add @civic/auth
pnpm install @civic/auth
bun add @civic/auth

2. Configure your App

Your app will need the following configuration:

const config = {
  clientId: // Client ID from auth.civic.com
  redirectUrl: 'http://localhost:3000/auth/callback', // change to your domain when deploying
  postLogoutRedirectUrl: 'http://localhost:3000/' // The postLogoutRedirectUrl is the URL where the user will be redirected after successfully logging out from Civic's auth server.
};

Note: redirectUrl and postLogoutRedirectUrl must be absolute URLs.

3. Set up Cookies

Civic Auth uses cookies for storing the login state by default

import { Context } from 'hono';
import { getCookie, setCookie } from 'hono/cookie';
import { CookieStorage, CivicAuth } from '@civic/auth/server';

class HonoCookieStorage extends CookieStorage {
  constructor(private c: Context) {
    super();
  }

  async get(key: string) {
    return getCookie(this.c, key) ?? null;
  }

  async set(key: string, value: string): void {
    setCookie(this.c, key, value);
  }
}

// Middleware to attach CookieStorage and civicAuth API to each request
app.use('*', async (c, next) => {
  const storage = new HonoCookieStorage(c)
  c.set('storage', storage);
  c.set('civicAuth', new CivicAuth(storage, config));
  return next();
});

4. Create a Login Endpoint

This endpoint will handle login requests, build the Civic login URL and redirect the user to it.

import { buildLoginUrl } from '@civic/auth/server';

app.get('/', async (c) => {
  const url = await c.get('civicAuth').buildLoginUrl();

  return c.redirect(url.toString());
});

5. Create the Callback Endpoint

This endpoint handles successful logins and creates the session

import { resolveOAuthAccessCode } from '@civic/auth/server';

app.get('/auth/callback', async (c) => {
  const code = c.req.query('code') as string
  const state = c.req.query('state') as string

  await c.get('civicAuth').resolveOAuthAccessCode(code, state);
  return c.redirect('/admin/hello');
});

6. Create a Logout Endpoint

This endpoint will handle logout requests, build the Civic logout URL and redirect the user to it.

import { buildLogoutRedirectUrl } from '@civic/auth/server';

app.get('/auth/logout', async (req: Request, res: Response) => {
  const url = await c.get('civicAuth').buildLogoutRedirectUrl();
  res.redirect(url.toString());
});

7. Add Middleware

Middleware protects routes that require login.

import { isLoggedIn } from '@civic/auth/server';

// Apply authentication middleware to any routes that need it
app.use('/admin/*', async (c, next) => {
  if (!c.get('civicAuth').isLoggedIn()) return c.text('Unauthorized', 401);

  return next();
});

8. Use the Session

If needed, get the logged-in user information.

import { user } from '@civic/auth/server';

app.get('/admin/hello', async (c) => {
  const user = await c.get('civicAuth').getUser();
  return c.text(`Hello, ${user?.name}!`);
});

PKCE and Client Secrets

When using the Civic Auth SDK, PKCE is handled entirely by the library.

Civic Auth uses , to protect users and clients from unauthorized access to user information. This, alongside domain registration for apps in production environments, mean that you don't need to provide a client secret in your backend.

Hono
github examples repo
PKCE (Proof Key for Code Exchange)