# Authentication from Browser

Inrupt provides the `@inrupt/solid-client-authn-browser` library to authenticate in a browser.

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

For applications implementing [Authorization Code Flow](https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowSteps):

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.

<figure><img src="https://2584838151-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLMLxFYifBOpjrf8rQMX1%2Fuploads%2Fgit-blob-207f8c5cf3aef0f5dea5f8a1e9e63cc211e63e67%2Flogin-flow.png?alt=media" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
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.
{% endhint %}

### Login Process

1. The application calls the library’s [login()](https://inrupt.github.io/solid-client-authn-js/browser/functions.html#login) function to start the process. To the function, the application passes in the following login options:

   <table data-header-hidden><thead><tr><th width="150.7578125"></th><th></th></tr></thead><tbody><tr><td><a href="https://inrupt.github.io/solid-client-authn-js/browser/interfaces/ILoginInputOptions.html#oidcissuer">oidcIssuer</a></td><td>Set to the user’s Solid Identity Provider (where the <em>login</em> function will send the user).</td></tr><tr><td><a href="https://inrupt.github.io/solid-client-authn-js/browser/interfaces/ILoginInputOptions.html#redirecturl">redirectUrl</a></td><td><p>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 <a href="https://inrupt.github.io/solid-client-authn-js/browser/functions.html#handleincomingredirect">handleIncomingRedirect()</a>).</p><div data-gb-custom-block data-tag="hint" data-style="warning" class="hint hint-warning"><p>Specify a static <code>redirectUrl</code> value that does not change with application routes or hash or query parameters.</p><p>For instance, instead of specifying <code>window.location.href</code> which might change for a Single Page Application (SPA) with multiple routes, you can use the URL constructor, such as <code>new URL("/path/to/redirectHandlingPage", window.location.href).toString()</code>.</p></div></td></tr><tr><td><a href="https://inrupt.github.io/solid-client-authn-js/browser/interfaces/ILoginInputOptions.html#clientname">clientName</a></td><td>(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 <code>clientName</code> is the name displayed during the approval step. If <code>clientName</code> is not provided, a random identifier is generated and used for the name.</td></tr><tr><td><code>customScopes</code></td><td>(Optional) Set of custom scopes requested by the client in addition to the default ones. This allows for application-specific claims to be added to the ID Token by the OpenID Provider.</td></tr></tbody></table>

   \
   For other options available to the function, see [ILoginInputOptions](https://inrupt.github.io/solid-client-authn-js/browser/interfaces/ILoginInputOptions.html).\\

   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()](https://inrupt.github.io/solid-client-authn-js/browser/functions.html#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.

{% hint style="info" %}
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](https://docs.inrupt.com/guides/authentication-in-solid/authentication-from-browser/session-restore-upon-browser-refresh).
{% endhint %}

Once logged in, the library’s [fetch()](https://inrupt.github.io/solid-client-authn-js/browser/functions.html#fetch) function can retrieve data using the available login information. You can pass this [fetch()](https://inrupt.github.io/solid-client-authn-js/browser/functions.html#fetch) function as an option to the `solid-client` functions (e.g., [getSolidDataset](https://inrupt.github.io/solid-client-js/modules/resource_solidDataset.html#getsoliddataset), [saveSolidDatasetAt](https://inrupt.github.io/solid-client-js/modules/resource_solidDataset.html#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()](https://inrupt.github.io/solid-client-authn-js/browser/functions.html#login) function to start the login process. That is, the login panel calls the below code to start the login process:

```javascript
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()](https://inrupt.github.io/solid-client-authn-js/browser/functions.html#login) with the following parameters:

<table data-header-hidden><thead><tr><th width="156.24609375"></th><th></th></tr></thead><tbody><tr><td><a href="https://inrupt.github.io/solid-client-authn-js/browser/interfaces/ILoginInputOptions.html#oidcissuer">oidcIssuer</a></td><td>Set to <code>"https://login.inrupt.com"</code>. (The example assumes the use of <a href="../../podspaces/podspaces">Inrupt PodSpaces</a>.)</td></tr><tr><td><a href="https://inrupt.github.io/solid-client-authn-js/browser/interfaces/ILoginInputOptions.html#redirecturl">redirectUrl</a></td><td>Set to <code>new URL("/callback", window.location.href).toString()</code>, which resolves to <code>https://myapp.example.com/callback</code></td></tr><tr><td><a href="https://inrupt.github.io/solid-client-authn-js/browser/interfaces/ILoginInputOptions.html#clientname">clientName</a></td><td>Set to <code>"My application"</code>.</td></tr></tbody></table>

The [login()](https://inrupt.github.io/solid-client-authn-js/browser/functions.html#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()](https://inrupt.github.io/solid-client-authn-js/browser/functions.html#handleincomingredirect) method to complete the login; specifically, it calls the below code which calls the [handleIncomingRedirect()](https://inrupt.github.io/solid-client-authn-js/browser/functions.html#handleincomingredirect) method:

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

// ...

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

#### Perform Authenticated Operations

Once authentication is complete, pass the [fetch()](https://inrupt.github.io/solid-client-authn-js/browser/classes/Session.html#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](https://inrupt.github.io/solid-client-js/modules/resource_solidDataset.html#getsoliddataset) and [saveSolidDatasetAt](https://inrupt.github.io/solid-client-js/modules/resource_solidDataset.html#savesoliddatasetat) calls:

```javascript
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 }
  );
}

// ...
```
