Privileged Authentication

Some operations require more privileged authentication β€” for example, if any user could invoke the transfer mutation, they would be able to transfer as many NFTs as they wanted to themselves, so we probably only want the application to be able to initiate that operation!

For operations that should only be initiated from the app or app admin's context, we support two forms of privileged authentication.

Backend Authentication

Backend authentication amounts to your application authenticating as itself, instead of in the AppUser context.

Backend authentication allows the App to perform any privileged operation against your application's resources.

For this reason, it's extremely important to only use this kind of authentication in your backend.

There are two ways of doing backend authentication - using your client secret or using OAuth.

  • Client Secret: Add your client secret header into the API Call (backend only).

  • Open ID and OAuth: Authenticate using the OAuth Client Credentials grant. Many OAuth libraries support this.

The following snippets show you both options:

Using a Client Secret
import { EnvironmentName, NiftoryClient } from "@niftory/sdk"
let client: NiftoryClient

/**
 * Gets a NIFTORY client for use in the backend.
 * @returns A NiftorySdk client.
 */
export function getBackendNiftoryClient() {
  client =
    client ||
    new NiftoryClient({
      environmentName: process.env.NEXT_PUBLIC_BLOCKCHAIN_ENV as EnvironmentName,
      appId: process.env.NEXT_PUBLIC_CLIENT_ID,
      apiKey: process.env.NEXT_PUBLIC_API_KEY,
      clientSecret: process.env.CLIENT_SECRET,
    })

  return client
}tu
Using an Open ID-Client
async function getOAuthClient() {
  if (
    !process.env.NEXT_PUBLIC_CLIENT_ID ||
    !process.env.CLIENT_SECRET ||
    !process.env.NIFTORY_AUTH_ISSUER
  ) {
    throw new Error(
      "NIFTORY_AUTH_ISSUER, NEXT_PUBLIC_CLIENT_ID, and CLIENT_SECRET must be set"
    );
  }

  if (!client) {
    const issuer = await Issuer.discover(process.env.NIFTORY_AUTH_ISSUER);
    client = new issuer.Client({
      client_id: process.env.NEXT_PUBLIC_CLIENT_ID,
      client_secret: process.env.CLIENT_SECRET,
    });
  }

  return client;
}

export async function getClientCredentialsToken() {
  const client = await getOAuthClient();

  if (!token || token.expired()) {
    token = await client.grant({ grant_type: "client_credentials" });
  }

  return token.access_token;
}

See Configuring Your App for details on these configuration values.

See the Quick Start to get these properties for your app.

In this example, NIFTORY_AUTH_ISSUER should be the Niftory Auth service endpoint, omitting the path since openid-client appends it by default.

Admin Authentication

This works exactly like User Authentication, but adding the admin scope to your OAuth configuration.

Admin Authentication will only succeed if the user trying to log in is already a member of your team.

Last updated