# Node.js (Backend/API)

Lightweight Node.js SDK for BlitzWare resource servers (APIs).

This package provides simple middleware for Express and Koa to validate incoming bearer tokens. It prefers token introspection (avoids shipping a shared signing secret) and also supports the common pattern of mounting a non-enforcing parser once and enforcing auth on a per-route basis.

{% hint style="info" %}
This tutorial is based on the [example app](https://github.com/LanderDK/blitzware-node-api-sdk/tree/master/examples).
{% endhint %}

1. [**Configure BlitzWare**](#configure-blitzware)
2. [**Install the BlitzWare Node API SDK**](#id-2-install-the-blitzware-node-api-sdk)
3. [**Configure environment**](#id-3-configure-environment)
4. [**Express setup**](#id-4-express-setup)
5. [**Koa setup**](#id-5-koa-setup)
6. [**How it works**](#id-6-how-it-works)

## 1) Configure BlitzWare <a href="#configure-blitzware" id="configure-blitzware"></a>

### Get Your Application Keys <a href="#get-your-application-keys" id="get-your-application-keys"></a>

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.

<figure><img src="https://3971581513-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYjb41by6V7VaMjHbf8VN%2Fuploads%2FwQUuApkYQcdaekNmrQIy%2Fspa_settings.png?alt=media&#x26;token=33781bdf-97e2-4ad5-aae8-d767017b70a6" alt=""><figcaption></figcaption></figure>

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 API SDK

Run the following command within your project directory to install the [BlitzWare Node API SDK](https://www.npmjs.com/package/blitzware-node-api-sdk):

{% code title="npm" overflow="wrap" lineNumbers="true" %}

```
npm install blitzware-node-api-sdk
```

{% endcode %}

{% code title="yarn" lineNumbers="true" %}

```
yarn add blitzware-node-api-sdk
```

{% endcode %}

## 3) Configure environment

Create a `.env` file:

```bash
BLITZWARE_CLIENT_ID=your-client-id
BLITZWARE_CLIENT_SECRET=your-client-secret
```

## 4) Express setup

{% code lineNumbers="true" %}

```javascript
const express = require("express");
require("dotenv").config();
const { expressAuth, expressRequireAuth } = require("blitzware-node-api-sdk");

const app = express();
app.use(express.json());

app.use(
  expressAuth({
    clientId: process.env.BLITZWARE_CLIENT_ID,
    clientSecret: process.env.BLITZWARE_CLIENT_SECRET,
  })
);

app.get("/public", (req, res) => res.json({ ok: true, public: true }));

app.get("/protected", expressRequireAuth(), (req, res) => {
  res.json({ ok: true, user: req.auth && req.auth.payload });
});

const port = process.env.PORT;
app.listen(port, () =>
  console.log(`Express API example listening on http://localhost:${port}`)
);
```

{% endcode %}

## 5) Koa setup

{% code lineNumbers="true" %}

```javascript
const Koa = require("koa");
const Router = require("@koa/router");
const bodyParser = require("koa-bodyparser");
require("dotenv").config();
const { koaAuth, koaRequireAuth } = require("blitzware-node-api-sdk");

const app = new Koa();
const router = new Router();
app.use(bodyParser());

app.use(
  koaAuth({
    clientId: process.env.BLITZWARE_CLIENT_ID,
    clientSecret: process.env.BLITZWARE_CLIENT_SECRET,
  })
);

router.get("/public", (ctx) => {
  ctx.body = { ok: true, public: true };
});

router.get("/protected", koaRequireAuth(), (ctx) => {
  ctx.body = { ok: true, user: ctx.state.auth && ctx.state.auth.payload };
});

app.use(router.routes()).use(router.allowedMethods());

const port = process.env.PORT;
app.listen(port, () =>
  console.log(`Koa API example listening on http://localhost:${port}`)
);
```

{% endcode %}

## 6) How it works

### What this package exports

* `expressAuth(options)` -> returns an Express parser middleware. Mount with `app.use(expressAuth(...))`.
* `expressRequireAuth()` -> returns an Express per-route enforcer middleware.
* `koaAuth(options)` -> returns a Koa parser middleware. Mount with `app.use(koaAuth(...))`.
* `koaRequireAuth()` -> returns a Koa per-route enforcer middleware.

These helpers are implemented in `src/middleware.ts` and re-exported from `src/index.ts` (the package entry).

### Quick concepts and recommended pattern

* Parser (non-enforcing): the middleware returned by `expressAuth()` / `koaAuth()` tries to parse and introspect a bearer token on every request and will attach the result to `req.auth` (Express) or `ctx.state.auth` (Koa) when a valid token is present. The parser does not block anonymous requests.
* Require (per-route): the middleware returned by `expressRequireAuth()` / `koaRequireAuth()` enforces authentication for a specific route. If `req.auth`/`ctx.state.auth` is missing, it will perform on-demand introspection using the options previously provided via `expressAuth()`/`koaAuth()` (the helpers store the config internally) and reject the request if the token is invalid or missing.

Recommended usage for multi-file projects:

1. In your main entrypoint mount the parser once so it runs on every request:

{% code lineNumbers="true" %}

```js
// app.js
require("dotenv").config();
const express = require("express");
const { expressAuth } = require("blitzware-node-api-sdk");

const app = express();
app.use(express.json());

// mount parser globally (non-enforcing)
app.use(
  expressAuth({
    clientId: process.env.BLITZWARE_CLIENT_ID,
    clientSecret: process.env.BLITZWARE_CLIENT_SECRET,
  })
);

app.get("/public", (req, res) => res.json({ ok: true }));

// mount routers or individual route files after this
app.use("/users", require("./routes/users"));

app.listen(process.env.PORT || 3000);
```

{% endcode %}

2. In each route file, use the per-route enforcer where you need protection:

{% code lineNumbers="true" %}

```js
// routes/users.js
const express = require("express");
const router = express.Router();
const { expressRequireAuth } = require("blitzware-node-api-sdk");

router.get("/", (req, res) => res.json({ ok: true, users: [] })); // public

router.get("/me", expressRequireAuth(), (req, res) => {
  // parse middleware attached req.auth earlier if token present
  res.json({ ok: true, me: req.auth && req.auth.payload });
});

module.exports = router;
```

{% endcode %}

This pattern avoids re-creating auth middleware in every route file while ensuring per-route enforcement works.
