Authenticate (Node.js: Single-User App)#

Inrupt provides the solid-client-authn-node library to authenticate in Node.js.

npm install @inrupt/solid-client-authn-node

Node.js: Single-User Application#

Your application can use the solid-client-authn-node library to handle the user authentication flow.

Although your application can start the authentication flow that involves browser-based user interactions with a Solid Identity Provider, as an alternative, you can separately obtain refresh tokens and client credentials for use in your application.

That is, if your Solid Identity Provider supports refresh tokens and/or client credentials as grant types, then:

  1. As a prereq, you can first obtain:

    • refresh token and client credentials (from dynamic or static registration of the application), or

    • client credentials from static registration of the application.

    This is done separately from the application.

  2. Then, in your application, you can use either:

    • refresh tokens and client credentials, or

    • client credentials only if the application is statically registered.

Refresh Tokens/Client Credentials Support

Solid Identity Providers are not required to support either refresh tokens or client credentials.

Inrupt’s ESS and PodSpaces support refresh tokens and client credentials.

Authenticate with Statically Registered Client Credentials#

Prerequisite#

If supported by your Solid Identity Provider, statically register your application. The registration results in a Client ID and Client Secret pair.

For example, if using the Solid Identity Provider for Inrupt’s Pod Spaces, you can statically register your application via its Inrupt Application Registration page.

Update Application Code#

For a statically registered application, you can use the solid-client-authn-node library with the client credentials for the the user authentication flow:

  1. Create a new Session for the user.

  2. Call the Session.login() function, passing in the ILoginInputOptions.

    Although you can pass in the options (oidcIssuer, redirectUrl, handleRedirect) to start the authentication flow, you can instead pass in the following options with the values obtained from the prerequisite section to login without the manual, browser-based user interactions:

    When login() returns, your session should be logged in and able to make authenticated requests.

Warning

Safeguard your clientId and clientSecret values. Do not share these with any third parties as anyone with your clientId and clientSecret values can impersonate you and act fully on your behalf.

Example#

The following single-user application calls Session.login() with:

  • clientId, clientSecret, and

  • oidcIssuer.

Warning

Safeguard your clientId and clientSecret values. Do not share these with any third parties as anyone with your clientId and clientSecret values can impersonate you and act fully on your behalf.

const { Session } = require("@inrupt/solid-client-authn-node");

// 1. Get the authenticated credentials: myClientId, myClientSecret
// and myIdentityProvider, the Solid Identity Provider associated with the credentials.
// ...
// ...
// Important: Safeguard these credentials.

const session = new Session();
session.login({
  // 2. Use the authenticated credentials to log in the session.
  clientId: myClientId,
  clientSecret: myClientSecret,
  oidcIssuer: myIdentityProvider
}).then(() => {
  if (session.info.isLoggedIn) {
    // 3. Your session should now be logged in, and able to make authenticated requests.
    session
      // You can change the fetched URL to a private resource, such as your Pod root.
      .fetch(session.info.webId)
      .then((response) => {
        return response.text();
      })
      .then(console.log);
  }
});

Static Registration of a Client Application#

If your Solid Identity Provider provides a mechanism to statically register applications, your applications can use the associated client credentials to login.

Availability#

Inrupt provides an Inrupt Application Registration where you can statically register your applications to generate credentials for them. It is available for users with accounts on https://login.inrupt.com; i.e., users who have registered a Pod with PodSpaces. To use, visit Inrupt Application Registration to register your client.

For availability of static client registration for your Solid Identity Provider, see your Solid Identity Provider’s documentation.

Authenticate with a Refresh Token#

Your application can use Refresh Token to get an Access Token. Access Tokens allows you to access Resources for which you have been authorized.

Prerequisite#

Obtain a Refresh Token and client credentials for your application.

For example, you can use Inrupt’s generate-oidc-token tool to obtain a Refresh Token and client credentials for your application.

Update Application Code#

To handle the authentication flow with the solid-client-authn-node library and a Refresh Token (and the client credentials):

  1. Create a new Session for the user.

  2. Call the Session.login() function, passing in the ILoginInputOptions.

    Although you can pass in the options (oidcIssuer, redirectUrl, handleRedirect) to start the authentication flow, you can instead pass in the following options with the values obtained from the prerequisite section to login without the manual, browser-based user interactions:

    When login() returns, your session should be logged in and able to make authenticated requests.

Warning

Safeguard your clientId, clientSecret, and refreshToken values. Do not share these with any third parties as anyone with your clientId, clientSecret, and refreshToken values can impersonate you and act fully on your behalf.

Example#

The following single-user application calls Session.login() with:

  • clientId, clientSecret, refreshToken, and

  • oidcIssuer.

Warning

Safeguard your clientId, clientSecret, and refreshToken values. Do not share these with any third parties as anyone with your clientId, clientSecret, and refreshToken values can impersonate you and act fully on your behalf.

const { Session } = require("@inrupt/solid-client-authn-node");

// 1. Get the authenticated credentials: 
//     myClientId, myClientSecret, myRefreshToken, myIdentityProvider
// ...
// ...
// Important: Safeguard these credentials.

const session = new Session();

// For the Session, specify the callback to invoke when the refresh token is updated by the Identity Provider.
session.onNewRefreshToken((newToken) => {
  console.log('New refresh token: ', newToken);
});

session.login({
  // 2. Use the authenticated credentials to log in the session.
  clientId: myClientId,
  clientSecret: myClientSecret,
  refreshToken: myRefreshToken,
  oidcIssuer: myIdentityProvider
}).then(() => {
  if (session.info.isLoggedIn) {
    // 3. Your session should now be logged in, and able to make authenticated requests.
    session
      // You can change the fetched URL to a private resource, such as your Pod root.
      .fetch(session.info.webId)
      .then((response) => {
        return response.text();
      })
      .then(console.log);
  }
});

Handling Refresh Token Rotation#

Refresh Tokens allow you to get a new Access Token when the previous Access Token expires. Refresh Tokens should be treated as sensitive data since the new Access Tokens allow authenticated access to resources. As such, it is considered good practice for Solid Identity Provider to implement a “Refresh Token rotation” process. That is, each time the client application uses a Refresh Token to get a new Access Token, a new Refresh Token is also returned. The previous Refresh Token is invalidated, and can no longer be used to get Access Tokens.

@inrupt/solid-client-authn-node has an internal mechanism to manage refresh tokens in the Session’s storage. For the Session’s storage, you can pass in a storage as an option to the Session constructor or use the default storage, which is an in-memory storage. If you pass in a persistent storage, the refresh token management is transparent. However, for Node.js applications that use the Session’s default in-memory storage, the storage (and hence the refresh token) is lost when the program stops.

As an alternative to providing a persistent storage to the Session constructor, you can pass in the onNewRefreshToken callback to the constructor instead. Then, each time a new refresh token is issued, the onNewRefreshToken callback is invoked with the new refresh token as a parameter. The onNewRefreshToken option allows you to run custom code to handle the refresh token as appropriate.

@inrupt/generate-oidc-token Utility#

Solid authentication involves redirecting the user to the Solid Identity Provider, and after the user logs in, redirecting the user back to the specified URL.

To help during the development of a single-user Node.js application, Inrupt provides a utility @inrupt/generate-oidc-token. The standalone utility takes a user through the authentication flow and upon successful authentication, outputs the Client ID, Client Secret, and Refresh Token. These artifacts can be used in your Node.js application so that the application does not have to go through the authentication flow during the development stage.

Note

  • The utility only supports logging in to Solid-OIDC compliant Identity Provider, such as https://login.inrupt.com or https://solidcommunity.net.

  • If you have already registered the client and have a Client ID and Secret, you can use them. Otherwise, the utility dynamically registers your client to return new Client ID and Secret.

  • Artifacts generated by the utility expire after 3 days; i.e.,

    • The Refresh Token expires after 3 days.

    • If the utility dynamically registered the client and returned the associated Client ID and Secret, the Client ID and Secret also expire after 3 days.

  1. In a terminal, run generate-oidc-token utility to log in to a

    npx @inrupt/generate-oidc-token
    

    The utility prompts the user for some information.

  2. Enter the appropriate values to the prompts.

    When finished, the utility asks the user to visit a site in a browser.

  3. Open the browser and visit the site. Log in to the Solid Identity Provider.

  4. Upon login, return to the terminal and you should see the following information:

    • Client ID

    • Client Secret

    • Refresh Token

Warning

Safeguard your Client ID, Client Secret, and Refresh Token values. Do not share these with any third parties as anyone with your Client ID, Client Secret, and Refresh Token values can impersonate you and act fully on your behalf.