|
| 1 | +# Authenticating with a Node.js Script |
| 2 | + |
| 3 | +Many Solid use cases — automated data pipelines, bots, CI/CD tasks, and server-to-server integrations — require authentication **without a browser**. This guide walks you through authenticating a Node.js script against a Solid server using **Client Credentials**. |
| 4 | + |
| 5 | +The approach works with any Solid server that supports the Client Credentials grant type, including the [Community Solid Server (CSS)](https://communitysolidserver.github.io/CommunitySolidServer/) and Inrupt's [Enterprise Solid Server (ESS)](https://docs.inrupt.com/). |
| 6 | + |
| 7 | +## Prerequisites |
| 8 | + |
| 9 | +- [Node.js](https://nodejs.org/) v18 or later (for built-in `fetch`) |
| 10 | +- A Solid account with a Pod on a server that supports Client Credentials |
| 11 | +- Basic familiarity with JavaScript |
| 12 | + |
| 13 | +## Overview |
| 14 | + |
| 15 | +The flow has three stages: |
| 16 | + |
| 17 | +1. **Generate a Client Credentials token** — obtain a `client_id` / `client_secret` pair linked to your WebID. This only needs to be done **once**. |
| 18 | +2. **Log in with the credentials** — use the `client_id` and `client_secret` to start an authenticated session. |
| 19 | +3. **Make authenticated requests** — use the session's `fetch` to read and write resources on your Pod. |
| 20 | + |
| 21 | +## 1. Set Up the Project |
| 22 | + |
| 23 | +Create a new directory and initialise it: |
| 24 | + |
| 25 | +```bash |
| 26 | +mkdir solid-script && cd solid-script |
| 27 | +npm init -y |
| 28 | +``` |
| 29 | + |
| 30 | +Set the project to use ES modules and install the required library: |
| 31 | + |
| 32 | +```bash |
| 33 | +npm pkg set type=module |
| 34 | +npm install @inrupt/solid-client-authn-node |
| 35 | +``` |
| 36 | + |
| 37 | +Create a file called `index.js` — all the code below goes into this file. |
| 38 | + |
| 39 | +## 2. Generate Client Credentials (One-Time Setup) |
| 40 | + |
| 41 | +Before your script can log in, you need a `client_id` / `client_secret` pair. There are two ways to get one: |
| 42 | + |
| 43 | +### Option A: Via the Account Page (easiest) |
| 44 | + |
| 45 | +If your Solid server has an account management UI, you can create a token there: |
| 46 | + |
| 47 | +1. Navigate to your account page: |
| 48 | + - **Community Solid Server (local)**: [http://localhost:3000/.account/](http://localhost:3000/.account/) |
| 49 | + - **solidcommunity.net**: [https://solidcommunity.net/.account/](https://solidcommunity.net/.account/) |
| 50 | + - **Inrupt PodSpaces**: [https://login.inrupt.com/registration.html](https://login.inrupt.com/registration.html) |
| 51 | +2. Create a new Client Credentials token, giving it a name and selecting your WebID. |
| 52 | +3. Copy the `id` and `secret` values shown. **Store the secret safely** — it cannot be retrieved again. |
| 53 | + |
| 54 | +Skip ahead to [Step 3](#3-log-in-and-make-authenticated-requests) if you use this approach. |
| 55 | + |
| 56 | +### Option B: Via the API (programmatic) |
| 57 | + |
| 58 | +Some Solid servers also allow you to generate credentials programmatically. This is useful for automation or when you don't have browser access. The process is server-specific — for example, the Community Solid Server provides a dedicated API for this: |
| 59 | + |
| 60 | +- [CSS — Generating a token via the API](https://communitysolidserver.github.io/CommunitySolidServer/latest/usage/client-credentials/#via-the-api) |
| 61 | + |
| 62 | +## 3. Log In and Make Authenticated Requests |
| 63 | + |
| 64 | +Once you have a `client_id` and `client_secret`, you can authenticate using the [`Session`](https://inrupt.github.io/solid-client-authn-js/node/classes/Session.html) class from `@inrupt/solid-client-authn-node`. |
| 65 | + |
| 66 | +Replace the contents of `index.js` (or create a new file) with: |
| 67 | + |
| 68 | +```javascript |
| 69 | +import { Session } from '@inrupt/solid-client-authn-node'; |
| 70 | + |
| 71 | +// These values come from Step 2 (or from your account page). |
| 72 | +// In production, load these from environment variables. |
| 73 | +const CLIENT_ID = process.env.SOLID_CLIENT_ID; |
| 74 | +const CLIENT_SECRET = process.env.SOLID_CLIENT_SECRET; |
| 75 | +const OIDC_ISSUER = 'http://localhost:3000'; // Your Solid server URL |
| 76 | + |
| 77 | +async function main() { |
| 78 | + // Create a new session and log in |
| 79 | + const session = new Session(); |
| 80 | + await session.login({ |
| 81 | + clientId: CLIENT_ID, |
| 82 | + clientSecret: CLIENT_SECRET, |
| 83 | + oidcIssuer: OIDC_ISSUER, |
| 84 | + }); |
| 85 | + |
| 86 | + if (!session.info.isLoggedIn) { |
| 87 | + throw new Error('Login failed'); |
| 88 | + } |
| 89 | + console.log(`Logged in as ${session.info.webId}`); |
| 90 | + |
| 91 | + // session.fetch works just like the standard fetch API, |
| 92 | + // but automatically includes authentication headers. |
| 93 | + const response = await session.fetch(session.info.webId); |
| 94 | + console.log(`GET ${session.info.webId} — ${response.status}`); |
| 95 | + console.log(await response.text()); |
| 96 | + |
| 97 | + // Always log out when done |
| 98 | + await session.logout(); |
| 99 | + console.log('Logged out.'); |
| 100 | +} |
| 101 | + |
| 102 | +main().catch(console.error); |
| 103 | +``` |
| 104 | + |
| 105 | +Run the script: |
| 106 | + |
| 107 | +```bash |
| 108 | +SOLID_CLIENT_ID="your-client-id" \ |
| 109 | +SOLID_CLIENT_SECRET="your-client-secret" \ |
| 110 | +node index.js |
| 111 | +``` |
| 112 | + |
| 113 | +You should see your profile document printed to the console. |
| 114 | + |
| 115 | +## Tips |
| 116 | + |
| 117 | +- **Token reuse**: The `client_id` / `client_secret` pair does not expire. Generate it once and reuse it across runs. Only the access tokens obtained during `session.login()` are short-lived — the library handles refreshing them automatically. |
| 118 | +- **Session keep-alive**: By default, the `Session` refreshes its tokens in the background. Pass `{ keepAlive: false }` to the `Session` constructor if you want a one-shot script that exits cleanly. |
| 119 | +- **Security**: Never hard-code secrets in source code. Use environment variables or a secrets manager. |
| 120 | +- **Multiple WebIDs**: You can generate multiple client credentials tokens, each linked to a different WebID on your account. |
| 121 | + |
| 122 | +## Further Reading |
| 123 | + |
| 124 | +- [Community Solid Server — Client Credentials documentation](https://communitysolidserver.github.io/CommunitySolidServer/latest/usage/client-credentials/) |
| 125 | +- [Inrupt — Authentication for Single-User Applications](https://docs.inrupt.com/developer-tools/javascript/client-libraries/tutorial/authenticate-nodejs-script/) |
| 126 | +- [`@inrupt/solid-client-authn-node` API reference](https://inrupt.github.io/solid-client-authn-js/node/classes/Session.html) |
| 127 | +- [Solid-OIDC specification](https://solid.github.io/solid-oidc/) |
0 commit comments