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

# ToolrinthLib OAuth2 Guide

> In this guide, you'll learn how to use the ToolrinthLib OAuth2 client to authorize users with Modrinth's API.

#### Packages in this Guide

<Columns cols="2">
  <Callout icon="box" color="#1B8051">[Express](https://npmjs.org/package/express) *v5.2.1*<br /><br />for the web server</Callout>
  <Callout icon="box" color="#1B8051">[@toolrinth/lib](https://npmjs.org/package/@toolrinth/lib) *v1.1.0*<br /><br />for Modrinth OAuth</Callout>
</Columns>

<Note>This guide does not cover token storage methods (cookies, localStorage, etc). It also does not cover security measures, such as state. It is expected that you know how to handle the data you receive. This guide is focused on the nuances of the ToolrinthLib OAuth2 client.</Note>

***

<Steps>
  <Step title="Create a Modrinth OAuth Application">
    To interact with Modrinth's OAuth API, you need to create an application in your [user application settings](https://modrinth.com/settings/applications)

    <Steps>
      <Step icon="letter-a">Head to your [Modrinth Application Settings](https://modrinth.com/settings/applications)</Step>
      <Step icon="letter-b">Choose `+ New application` to create an application</Step>
      <Step icon="letter-c">Enter an Application name. We'll use "ToolrinthLib Tutorial" for this guide.</Step>

      <Step icon="letter-d">
        From the list of scopes, choose the following:

        * **Read user data**
        * **Read projects**
        * **Read versions**
        * **Read organizations**
      </Step>

      <Step icon="letter-e">Enter the redirect url: `http://localhost:3000`</Step>
      <Step icon="letter-f">Choose `+ Create app` to create the application</Step>
    </Steps>
  </Step>

  <Step title="Create a ToolrinthLib Project">
    Create a barebones NPM project, and install the following packages:

    * **express**
    * **@toolrinth/lib**

    ```sh theme={"theme":"github-dark-high-contrast"}
    npm install express @toolrinth/lib
    ```

    Create the entrypoint file:

    ```sh theme={"theme":"github-dark-high-contrast"}
    touch index.js
    ```
  </Step>

  <Step title="Set up the Project">
    First things first, we need to create our Express server and the ToolrinthLib OAuth2 client. We also need to listen for GET requests on the root path (`/`)

    <Expandable title="Code">
      <CodeGroup>
        ```javascript index.js theme={"theme":"github-dark-high-contrast"}
        import express from "express";
        import { OAuth2 } from "@toolrinth/lib";

        const PORT = 3000;

        // Replace with the Client ID and Client Secret of your Modrinth application
        const CLIENT_ID = "...your client ID";
        const CLIENT_SECRET = "...your client secret";

        // Request all of the scopes we added to the Modrinth application
        const SCOPES = [
          OAuth2.Scopes.USER_READ,
          OAuth2.Scopes.PROJECT_READ,
          OAuth2.Scopes.VERSION_READ,
          OAuth2.Scopes.ORGANIZATION_READ,
        ];

        // Create the Express Webserver
        const app = express();

        // Create the ToolrinthLib OAuth2 Client
        const oauth2 = new OAuth2.Client(
          CLIENT_ID,
          CLIENT_SECRET,
          "http://localhost:3000",
          SCOPES
        );

        // Listen for GET requests on http://localhost:3000/
        app.get("/", async (request, response) => {

          // Respond to the client. We will replace this soon.
          response.send("Hello World!");

        });

        // Start Express on port 3000
        app.listen(PORT);

        ```
      </CodeGroup>
    </Expandable>

    Start the webserver with `node index.js`
  </Step>

  <Step title="Listen for Requests">
    Now that our webserver is online, we need to check whether or not incoming requests contain an [authorization code](https://oauth.net/2/grant-types/authorization-code/), and act accordingly.

    <Expandable title="Code">
      <CodeGroup>
        ```javascript index.js theme={"theme":"github-dark-high-contrast"}
        ...


        // Listen for GET requests on http://localhost:3000/
        app.get("/", async (request, response) => {

          // Authorization codes are passed as the "code" query parameter
          const code = req.query?.code || null;

          if (!code) {

            // If there is no code, we need to redirect the user to Modrinth to authorize.
            //
            // getRedirectUrl() provides a "state" value, which should be used to ensure security when authenticating users.
            const urlResponse = oauth2.getRedirectUrl();

            // Redirect the user to Modrinth to authorize
            response.redirect(urlResponse.redirect_url);

          } else {

            // The user has been through Modrinth authentication.
            //
            // Soon, we'll swap the authorization code for an access token to use with Modrinth's API

          }

        });

        ...

        ```
      </CodeGroup>
    </Expandable>
  </Step>

  <Step title="Obtain an Access Token">
    One you have an authorization code, you can use `OAuth2.Client#exchangeCode()` to obtain an access token for use with the Modrinth API.

    <Expandable title="Code">
      <CodeGroup>
        ```javascript index.js theme={"theme":"github-dark-high-contrast"}
        ...


        } else {

          // Exchange the authorization code for an access token
          const { data, error } = await oauth2.exchangeCode(code);

          if (error) return response.sendStatus(error.status);

          response.send(`Your token is: ${data.access_token}`); // Do not do this (duh)

        }

        ...

        ```
      </CodeGroup>
    </Expandable>
  </Step>
</Steps>
