Node.js (Traditional Web App)
This tutorial demonstrates how to add user login to a Node application using BlitzWare.
Build a secure server‑rendered web app using BlitzWare OAuth 2.0 Authorization Code + PKCE with the BlitzWare Node SDK.
1) Configure BlitzWare
Get Your Application Keys
You will need some details about your application to communicate with BlitzWare. You can get these details from the Application Settings section in the BlitzWare dashboard.

You need the Client ID and Client Secret (given when app was created).
Configure Redirect URIs
A redirect URI is a URL in your application where BlitzWare redirects the user after they have authenticated. The redirect URI for your app must be added to the Redirect URIs list in your Application Settings under the Security tab. If this is not set, users will be unable to log in to the application and will get an error.
2) Install the BlitzWare Node Web SDK
Run the following command within your project directory to install the BlitzWare Node Web SDK:
npm install blitzware-node-web-sdk
yarn add blitzware-node-web-sdk
3) Configure environment
Create a .env
file:
BLITZWARE_CLIENT_ID=your-client-id
BLITZWARE_CLIENT_SECRET=your-client-secret
BLITZWARE_REDIRECT_URI=http://localhost:3000/callback
SESSION_SECRET=replace-with-a-strong-secret
# Optional: override auth base (self-hosted/staging)
# BLITZWARE_BASE_URL=https://auth.blitzware.xyz/api/auth
4) Express setup
const path = require("path");
require("dotenv").config({ path: path.join(__dirname, "../.env") });
const express = require("express");
const session = require("express-session");
const { expressAuth, expressRequiresAuth } = require("blitzware-node-web-sdk");
const app = express();
const port = process.env.PORT || 3000;
// BlitzWare configuration
const config = {
authRequired: false, // Don't require auth for all routes
clientId: process.env.BLITZWARE_CLIENT_ID || "your-client-id",
clientSecret: process.env.BLITZWARE_CLIENT_SECRET || "your-client-secret",
redirectUri:
process.env.BLITZWARE_REDIRECT_URI || `http://localhost:${port}/callback`,
secret: process.env.SESSION_SECRET || "LONG_RANDOM_STRING",
// baseUrl: process.env.BLITZWARE_BASE_URL, // Optional: custom auth server
};
// Session middleware (required for auth middleware)
app.use(
session({
secret: config.secret,
resave: false,
saveUninitialized: false,
})
);
// Parse JSON bodies
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// BlitzWare auth router attaches /login, /logout, and /callback routes
app.use(expressAuth(config));
// Home route - req.session.user is provided from the auth router
app.get("/", (req, res) => {
res.send(`
<html>
<head><title>BlitzWare Express Example</title></head>
<body>
<h1>BlitzWare Express Example</h1>
${
req.session.user
? `
<p>✅ <strong>Logged in as ${req.session.user.username}</strong></p>
<p><a href="/profile">View Profile</a></p>
<p><a href="/logout">Logout</a></p>
`
: `
<p>❌ Not logged in</p>
<p><a href="/login">Login</a></p>
`
}
</body>
</html>
`);
});
// Protected profile route - expressRequiresAuth() middleware
app.get("/profile", expressRequiresAuth(), (req, res) => {
res.send(`
<html>
<head><title>Profile</title></head>
<body>
<h1>Profile</h1>
<pre>${JSON.stringify(req.session.user, null, 2)}</pre>
<p><a href="/">← Back to Home</a></p>
</body>
</html>
`);
});
app.listen(port, () => {
console.log(`
🚀 BlitzWare Express Example running at http://localhost:${port}
🔗 Routes:
• GET / - Home page
• GET /profile - Protected profile page
• GET /login - Login (automatic)
• GET /logout - Logout (automatic)
📝 Setup:
1. Set BLITZWARE_CLIENT_ID and BLITZWARE_CLIENT_SECRET in .env
2. Visit http://localhost:${port}/login to authenticate
`);
});
module.exports = app;
5) Koa setup
const path = require("path");
require("dotenv").config({ path: path.join(__dirname, "../.env") });
const Koa = require("koa");
const Router = require("@koa/router");
const KoaSession = require("koa-session");
const session =
KoaSession && KoaSession.default ? KoaSession.default : KoaSession;
const bodyParser = require("koa-bodyparser");
const { koaAuth, koaRequiresAuth } = require("blitzware-node-web-sdk");
const app = new Koa();
const router = new Router();
const port = process.env.PORT || 3001;
// BlitzWare configuration
const config = {
authRequired: false, // Don't require auth for all routes
clientId: process.env.BLITZWARE_CLIENT_ID || "your-client-id",
clientSecret: process.env.BLITZWARE_CLIENT_SECRET || "your-client-secret",
redirectUri:
process.env.BLITZWARE_REDIRECT_URI || `http://localhost:${port}/callback`,
secret: process.env.SESSION_SECRET || "LONG_RANDOM_STRING",
// baseUrl: process.env.BLITZWARE_BASE_URL, // Optional: custom auth server
};
// Koa requires signing keys for sessions
app.keys = [config.secret];
// Session middleware
app.use(session(app));
app.use(bodyParser());
// BlitzWare auth router attaches /login, /logout, and /callback routes
app.use(koaAuth(config));
// Home route - ctx.session.user is provided from the auth router
router.get("/", async (ctx) => {
ctx.type = "html";
ctx.body = `
<html>
<head><title>BlitzWare Koa Example</title></head>
<body>
<h1>BlitzWare Koa Example</h1>
${
ctx.session.user
? `
<p>✅ <strong>Logged in as ${ctx.session.user.username}</strong></p>
<p><a href="/profile">View Profile</a></p>
<p><a href="/logout">Logout</a></p>
`
: `
<p>❌ Not logged in</p>
<p><a href="/login">Login</a></p>
`
}
</body>
</html>
`;
});
// Protected profile route - koaRequiresAuth() middleware
router.get("/profile", koaRequiresAuth(), async (ctx) => {
ctx.type = "html";
ctx.body = `
<html>
<head><title>Profile</title></head>
<body>
<h1>Profile</h1>
<pre>${JSON.stringify(ctx.session.user, null, 2)}</pre>
<p><a href="/">← Back to Home</a></p>
</body>
</html>
`;
});
app.use(router.routes());
app.use(router.allowedMethods());
app.listen(port, () => {
console.log(`
🚀 BlitzWare Koa Example running at http://localhost:${port}
🔗 Routes:
• GET / - Home page
• GET /profile - Protected profile page
• GET /login - Login (automatic)
• GET /logout - Logout (automatic)
📝 Setup:
1. Set BLITZWARE_CLIENT_ID and BLITZWARE_CLIENT_SECRET in .env
2. Visit http://localhost:${port}/login to authenticate
`);
});
6) How it works
PKCE + state: The SDK generates a state and PKCE verifier/challenge; state defends against CSRF; PKCE protects the code exchange.
Automatic Routes
When you use
expressAuth()
orkoaAuth()
, the following routes are automatically created:GET /login
- Initiates OAuth login flowGET /logout
- Logs out user and clears sessionGET /callback
- OAuth callback handler
Protection:
expressRequiresAuth
andkoaRequiresAuth
: checks user presence in session.
Logout (front-channel): Performs a browser POST to the auth service so its session cookies are sent, then redirects back.
Last updated
Was this helpful?