Follow these simple steps to set up Civic Auth with an backend (a working example is available in our ).
1. Install dependencies
npm install @civic/auth cookies-parser
yarn add @civic/auth cookies-parser
pnpm install @civic/auth cookies-parser
bun add @civic/auth cookies-parser
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 express, { Request, Response } from 'express';
import { CookieStorage, CivicAuth } from '@civic/auth/server';
import cookieParser from 'cookie-parser';
app.use(cookieParser());
// Tell Civic how to get cookies from your node server
class ExpressCookieStorage extends CookieStorage {
constructor(private req: Request, private res: Response) {
super({
secure: false
})
}
async get(key: string): Promise<string | null> {
return Promise.resolve(this.req.cookies[key] ?? null);
}
async set(key: string, value: string): Promise<void> {
await this.res.cookie(key, value, this.settings);
}
}
app.use((req, res, next) => {
// add an instance of the cookie storage and civicAuth api to each request
req.storage = new ExpressCookieStorage(req, res);
req.civicAuth = new CivicAuth(req.storage, config);
next();
});
4. Create a Login Endpoint
This endpoint will handle login requests, build the Civic login URL and redirect the user to it.
import { isLoggedIn } from '@civic/auth/server';
const authMiddleware = async (req: Request, res: Response, next: NextFunction) => {
if (!(await req.civicAuth.isLoggedIn())) return res.status(401).send('Unauthorized');
next();
};
// Apply authentication middleware to any routes that need it
app.use('/admin', authMiddleware);
8. Use the Session
If needed, get the logged-in user information.
import { user } from '@civic/auth/server';
app.get('/admin/hello', async (req: Request, res: Response) => {
const user = await req.civicAuth.getUser();
res.send(`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.