MonoShop is a sample storefront that demonstrates how Node.js APIs can validate and use MonoCloud issued access tokens.
The demo includes a Next.js front end and two Express APIs. Users sign in through MonoCloud, the Next.js app gets an access token, and the APIs validate that token before returning protected data.
This example shows how to build APIs that enforce:
- Valid MonoCloud issued bearer tokens
- API specific audiences
- Route level scopes
- Token based access from a frontend application
monoshop-api-demo
├── apps
│ └── web # Next.js app that signs users in and calls the APIs
└── services
├── product-api # Express API for product data (port 4001)
└── invoice-api # Express API for invoice data (port 4002)
Each API is modeled as a separate protected resource with its own audience and scope requirements.
| Service | Audience | Protected route | Required scope |
|---|---|---|---|
| Product API | http://api.monoshop.com/products |
GET /products |
read:products |
| Invoice API | http://api.monoshop.com/invoices |
GET /invoices |
read:invoices |
- The user signs in to the Next.js app using MonoCloud.
- The app requests access to the Product API and Invoice API.
- MonoCloud issues access tokens for the requested API resources.
- The Next.js app forwards the access token to the APIs using the
Authorization: Bearer <token>header. - Each Express API validates the token using the MonoCloud Node.js Backend SDK.
- The API checks the token audience and required scope before returning data.
- Express API protection: Protect routes using middleware from
@monocloud/backend-node. - Audience-aware token validation: Each API only accepts tokens issued for its own audience.
- Scoped authorization: Routes require specific scopes such as
read:productsorread:invoices. - Frontend-to-API bearer token forwarding: The Next.js app uses
getTokens()to retrieve access tokens from the user session and sends them to the APIs. - Multi-API demo setup: The storefront calls two separate APIs, each with its own authorization rules.
- Node.js 20 or later
- npm 10 or later
- A MonoCloud account
-
Clone the repository:
git clone https://github.com/monocloud/monoshop-api-demo.git cd monoshop-api-demo -
Install dependencies:
npm install
-
Configure environment variables
Each app and service includes an
.env.examplefile. Copy each one to.envand fill in the required values from your MonoCloud dashboard.apps/web/.env.example services/product-api/.env.example services/invoice-api/.env.example -
Start every app in the workspace:
npm run dev
Open http://localhost:3000 in your browser. After signing in, the dashboard calls both protected APIs and renders their data.
With the services running, call each API directly without a token:
curl http://localhost:4001/products
curl http://localhost:4002/invoicesBoth requests return 401 Unauthorized because the routes require a valid bearer token.
To call an API successfully, send a valid MonoCloud issued access token with the correct audience and scope:
curl http://localhost:4001/products \
-H "Authorization: Bearer <access_token>"The Product API requires an access token with:
audience: http://api.monoshop.com/products
scope: read:products
The Invoice API requires an access token with:
audience: http://api.monoshop.com/invoices
scope: read:invoices
Use MonoShop as a reference for building applications with:
- Protected Node.js APIs
- Express middleware-based token validation
- Audience-specific access tokens
- Scoped API authorization
- Frontend-to-backend bearer token calls
- Multiple APIs protected by the same identity platform