> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pylon.mortgage/llms.txt
> Use this file to discover all available pages before exploring further.

# Handling authentication

> Set up backend authentication for Pylon Elements

Pylon Elements integrate with your existing authentication. When users are logged into your application, they're automatically logged into Pylon-no separate login required.

Elements use an **authorization lease** to communicate with the Pylon API. Before building Elements into your app, implement an auth handshake in your backend.

## How it works

<Steps>
  <Step title="Create a Contributor">
    When your authenticated user accesses Elements, create a Contributor record in Pylon's system with the user's name and email.
  </Step>

  <Step title="Request authorization lease">
    When the user wants to use Elements, your backend requests a new authorization lease for the user's Contributor.
  </Step>

  <Step title="Return lease to frontend">
    Your backend receives the authorization lease from Pylon and passes it to the Elements component.
  </Step>

  <Step title="Element loads">
    The Element uses the lease to securely communicate with the Pylon API.
  </Step>
</Steps>

<Info>
  This is a one-time setup. Once configured, all Elements in your application will use the same auth handshake.
</Info>

## Prerequisites

Before setting up authentication, ensure you can [authenticate with the Pylon API](/playground/authentication) using OAuth 2.0 Client Credentials.

## Implementation steps

### Step 1: Create a new route

Create an endpoint on your backend (we'll use `/auth/pylon` as an example). This route should:

* Return `401` unless accessed by a logged-in user
* Gather information about the logged-in user
* Get an authorization lease from the Pylon API
* Return the lease for use in Elements

### Step 2: Gather user information

In your backend route handler, collect the following from your logged-in user:

| User info                  | Why we need it                                                                   |
| -------------------------- | -------------------------------------------------------------------------------- |
| `firstName` and `lastName` | We need to know who this user is to contact them throughout the mortgage process |
| `email`                    | We need to contact this user throughout various steps of the mortgage process    |

### Step 3: Create or retrieve Contributor

Use the Pylon API's `contributor { createContributor }` mutation to create or retrieve a Contributor record:

```graphql theme={null}
mutation CreatePylonContributor($input: CreateContributorInput!) {
  contributor {
    createContributor(input: $input) {
      contributor { id }
    }
  }
}
```

**Variables:**

```json theme={null}
{
  "input": {
    "role": "BORROWER",
    "contactInfo": {
      "email": "user@example.com",
      "firstName": "John",
      "lastName": "Doe"
    }
  }
}
```

**Response:**

```json theme={null}
{
  "data": {
    "contributor": {
      "createContributor": {
        "contributor": {
          "id": "cont_123ABC456EXAMPLE"
        }
      }
    }
  }
}
```

<Warning>
  Save the `contributorId` in your database for future reference. You'll need it to create leases.
</Warning>

### Step 4: Create authorization lease

Use the `contributor { createLease }` mutation with the `contributorId`:

```graphql theme={null}
mutation CreatePylonLease($input: ContributorCreateLeaseInput!) {
  contributor {
    createLease(input: $input) {
      lease {
        id
        apiUrl
      }
    }
  }
}
```

**Variables:**

```json theme={null}
{
  "input": {
    "contributorId": "cont_123ABC456EXAMPLE"
  }
}
```

**Response:**

```json theme={null}
{
  "data": {
    "contributor": {
      "createLease": {
        "lease": {
          "id": "leas_ZXCV1234ASEXAMPLE",
          "apiUrl": "https://pylon.mortgage"
        }
      }
    }
  }
}
```

<Warning>
  Return the entire lease object to your frontend. Modifying or filtering the object may cause Elements not to load successfully.
</Warning>

## Example implementation

### Nest.js example

```typescript title="src/auth/pylon.service.ts" theme={null}
async createPylonContributor(user: User) {
  const input = {
    role: "BORROWER",
    contactInfo: {
      email: user.email,
      firstName: user.firstName,
      lastName: user.lastName,
    },
  };

  const headers = {
    "Content-Type": "application/json",
    "Authorization": `Bearer ${this.oauthToken}`,
  };

  const response = await axios.post(
    "https://pylon.mortgage/graphql",
    {
      query: `
      mutation CreatePylonContributor($input: CreateContributorInput!) {
        contributor {
          createContributor(input: $input) {
            contributor { id }
          }
        }
      }`,
      variables: { input },
    },
    { headers }
  );

  const pylonContributorId =
    response.data.contributor.createContributor.contributor.id;

  user.pylonContributorId = pylonContributorId;
  await this.usersDatabase.save(user);

  return pylonContributorId;
}
```

```typescript title="src/auth/pylon.controller.ts" theme={null}
@Post('/auth/pylon')
@UseGuards(LoggedIn) // Only accessible to logged in users
async pylonHandshake(@CurrentUser() user: User) {
  // Get contributor ID (existing or create new)
  const contributorId = user.pylonContributorId ||
    (await this.service.createPylonContributor(user));

  const headers = {
    "Content-Type": "application/json",
    "Authorization": `Bearer ${this.oauthToken}`,
  };

  // Request to create lease
  const response = await axios.post(
    "https://pylon.mortgage/graphql",
    {
      query: `
      mutation CreatePylonLease($input: ContributorCreateLeaseInput!) {
        contributor {
          createLease(input: $input) {
            lease { id apiUrl }
          }
        }
      }`,
      variables: {
        input: { contributorId }
      },
    },
    { headers }
  );

  const lease = response.data.contributor.createLease.lease;

  return lease;
}
```

## Implement logout

When a user logs out of your platform, destroy the Pylon session:

```typescript theme={null}
import { useSession } from "@pylonlending/react-elements";

const App = () => {
  const { destroy } = useSession();

  const onLogout = () => {
    // Your logout logic
    destroy(); // Destroy Pylon session
  };

  return (
    // Your app components
  );
};
```

## Content Security Policy (CSP)

If you're using a Content Security Policy, add these directives:

```
default-src https://api.{customer-id}.{env}.pylon.mortgage
frame-src https://api.{customer-id}.{env}.pylon.mortgage
script-src https://api.{customer-id}.{env}.pylon.mortgage/elements/pylon.js
connect-src https://api.{customer-id}.{env}.pylon.mortgage
```

Replace `{customer-id}` with your customer ID and `{env}` with `test` or `prod`.

## Next steps

With authentication configured, you can now build Elements into your app:

* [Loan Application Element](/elements/loan-application/introduction) - Start here for new applications
* [Borrower Dashboard Element](/elements/borrower-dashboard/introduction) - For managing existing loans
