Authenticate (Browser)#

Inrupt provides the solid-client-authn-browser library to authenticate in a browser.

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

For applications implementing Authorization Code Flow:

  1. The application starts the login process by sending the user to the user’s Solid Identity Provider.

  2. The user logs in to the Solid Identity Provider.

  3. The Solid Identity Provider sends the user back to your application, where the application handles the returned authentication information to complete the login process.

Login Flow: 1) Start Login by redirecting user to Solid Identity Provider. 2) User logs in.  3) Solid Identity Provider redirects the user back to the application to handle the returned authentication information.

Important

The login is only complete after the user is redirected back to the application; i.e., your application must be reloaded between the start of the login and its completion.

Login Process#

  1. The application calls the library’s login() function to start the process. To the function, the application passes in the following login options:

    oidcIssuer

    Set to the user’s Solid Identity Provider (where the login function will send the user).

    redirectUrl

    Set to the location where the Solid Identity Provider will send the user back once logged in and where the application can complete the login process (i.e., call handleIncomingRedirect()).

    Important

    Specify a static redirectUrl value that does not change with application routes or hash or query parameters.

    For instance, instead of specifying window.location.href which might change for a Single Page Application (SPA) with multiple routes, you can use the URL constructor, such as new URL("/path/to/redirectHandlingPage", window.location.href).toString().

    clientName

    (Optional) Set to the display name for the client. During the login process, the user has to approve the client’s access to the requested data (such as the user’s WebID). The clientName is the name displayed during the approval step. If clientName is not provided, a random identifier is generated and used for the name.

    For other options available to the function, see ILoginInputOptions.

    This process redirects the user from your application to the Solid Identity Provider.

  2. Once redirected to the Solid Identity Provider, the user logs in.

    Upon successful login, the Solid Identity Provider sends the user back to your application, namely to the redirectUrl specified in the login.

  3. From the redirectUrl page, the application calls the library’s handleIncomingRedirect() to complete the login process. The function collects the information provided by the Solid Identity Provider.

    The session is logged in only after it handles the incoming redirect from the Solid Identity Provider.

    Note

    By default, refreshing the current page logs out the user. To mitigate this and offer a better user experience, see Session Restore upon Browser Refresh.

Once logged in, the library’s fetch() function can retrieve data using the available login information. You can pass this fetch() function as an option to the solid-client functions (e.g., getSolidDataset, saveSolidDatasetAt) to include the user’s credentials with a request.

Example#

The example uses a single-user/single-Session application https://myapp.example.com that includes the following routes:

  • https://myapp.example.com/callback

  • https://myapp.example.com/todolist

The example assumes the use of Inrupt PodSpaces (i.e., the Identity Provider is https://login.inrupt.com).

Start Login#

The application has a login panel at the top, which calls the solid-client-authn-browser library’s login() function to start the login process. That is, the login panel calls the below code to start the login process:

import {  login, getDefaultSession } from '@inrupt/solid-client-authn-browser'

// ...

async function startLogin() {
  // Start the Login Process if not already logged in.
  if (!getDefaultSession().info.isLoggedIn) {
    await login({
      oidcIssuer: "https://login.inrupt.com",
      redirectUrl: new URL("/callback", window.location.href).toString(),
      clientName: "My application"
    });
  }
}

The app calls login() with the following parameters:

oidcIssuer

Set to "https://login.inrupt.com". (The example assumes the use of Inrupt PodSpaces.)

redirectUrl

Set to new URL("/callback", window.location.href).toString(), which resolves to https://myapp.example.com/callback

clientName

Set to "My application".

The login() sends the user to the specified oidcIssuer, in this example https://login.inrupt.com. The user logs in and is redirected back to the redirectUrl to complete the login process.

Complete Login#

Once the user logs in, the user is redirected back to redirectUrl. For the application, the redirectUrl value is new URL("/callback", window.location.href).toString(), which resolves to https://myapp.example.com/callback.

The page at redirectUrl calls the solid-client-authn-browser library’s handleIncomingRedirect() method to complete the login; specifically, it calls the below code which calls the handleIncomingRedirect() method:

import { handleIncomingRedirect } from '@inrupt/solid-client-authn-browser'

// ...

async function completeLogin() {
   await handleIncomingRedirect();
}

Perform Authenticated Operations#

Once authentication is complete, pass the fetch() function (from the authenticated user’s Session) as an option to various solid-client functions to read and write data to a Pod where the logged-in user has the appropriate access.

For example, after the user has authenticated, the app can call the following code to make authenticated getSolidDataset and saveSolidDatasetAt calls:

import { fetch } from '@inrupt/solid-client-authn-browser'
import { getSolidDataset, saveSolidDatasetAt } from "@inrupt/solid-client";

async function readTodoList() {

  // Make authenticated requests by passing `fetch` to the solid-client functions.
  // The user must have logged in as someone with the appropriate access to the specified URL.

  // For example, the user must be someone with Read access to the specified URL.
  const myDataset = await getSolidDataset(
    "https://storage.inrupt.com/somepod/todolist",
    { fetch: fetch }
  );
}

async function updateToDoList(myChangedDataset) {

  // The user must be someone with Write access to the specified URL.
  const savedSolidDataset = await saveSolidDatasetAt(
    "https://storage.inrupt.com/somepod/todolist",
    myChangedDataset,
    { fetch: fetch }
  );
}

// ...

For more information on reading and writing to a Pod, see: