Exchanging and using app tokens
#Overview
This document shows how to generate an app token for your app, while your app is installing. Make sure you have the ClientID
and the Client Secret
of your app before you start.
Please note that Client ID
and Client Secret
should be kept secret and must not be stored in your repository with your app code.
#Step by step
Assuming you created your app using create-next-app
, your app's setup page should look similar to the example below if you're working with app tokens. Notice the section under the comment, which you need to modify as in the example:
import { useApp, Wrapper } from '@hygraph/app-sdk-react';function Setup({ code }: { code: string }) {const { context } = useApp();const managementApiBaseUrl = context.project.mgmtApi.split("/").slice(0, -1).join("/");return (<ButtononClick={() =>fetch(`/api/saveAppToken`, {method: 'POST',headers: { 'Content-Type': 'application/json' },body: JSON.stringify({code,environmentId: context.environment.id,managementApiBaseUrl,}),}).then((res) => res.json()).then((data) => {// Save token to localstoragelocalStorage.setItem('app-token', data.appToken);})}>Get App Token</Button>);}// You'll get the exchange code in your setup page as query param only while// your App Installation is not completedexport default function SetupPage() {const { query } = useRouter();return (<Wrapper><Setup code={query.code as string} /></Wrapper>);}
Using localStorage
is an unsafe way to store app tokens. Please note that we're only using it here as an example.
In the above example const { query } = useRouter()
was added to get the code from the query, and Setup code={query.code as string}
was added to pass the code in the setup component.
The next step is to create a new API route /api/saveAppToken.ts
. This is the file where your app token will be generated:
export default async function handler(req: NextApiRequest,res: NextApiResponse<Data>) {const body = req.body as { code: string; environmentId: string; managementApiBaseUrl: string; };const response = await fetch(`${managementApiBaseUrl}/app-exchange-token`, {method: 'POST',headers: { 'Content-Type': 'application/json' },body: JSON.stringify({clientId: process.env.CLIENT_ID,clientSecret: process.env.CLIENT_SECRET,exchangeCode: req.body.code,}),});const { appToken } = (await response.json()) as { appToken: string };// Return App token to the browser so it can save it in localstorageres.status(200).json({ appToken });}
Now you can pass the saved app token in your header for authorization. For example, to create a new model using the saved app token, you can create another API route /api/createHygraphModel.ts
:
const createModelMutation = `mutation CreateModelMutation($input: CreateModelInput!) {createModel(data: $input) {migration {id}}}`;export default async function handler(req: NextApiRequest,res: NextApiResponse<Data>) {// Get App token from the client, saved in localstorage, in the request bodyconst body = req.body as { appToken: string; environmentId: string; managementApiUrl: string; };const response = await fetch(managementApiUrl, {method: 'POST',headers: {'Content-Type': 'application/json',Authorization: `Bearer ${body.appToken}`,},body: JSON.stringify({query: createModelMutation,variables: {input: {environmentId: body.environmentId,apiId: '<your_model_api_id>',apiIdPlural: '<your_model_api_id_plural>',displayName: '<Your model display name>',description: '<Your model description>',},},}),});res.status(200).json(response);}
And here is the frontend code for invoking this API route:
import { useApp, Wrapper } from '@hygraph/app-sdk-react';function CreateHygraphModel({ code }: { code: string }) {const { context } = useApp();const managementApiUrl = context.project.mgmtApi;return (<ButtononClick={() =>fetch(`/api/createHygraphModel`, {method: 'POST',headers: { 'Content-Type': 'application/json' },body: JSON.stringify({appToken: /* Get Saved App Token */,environmentId: context.environment.id,managementApiUrl,}),}).then((res) => res.json()).then((data) => {console.log('🎉 Created Hygraph Model');})}>Create Hygraph Model</Button>);}// Remember to wrap the component in Hygraph App Wrapperexport default function SetupPage() {const { query } = useRouter();return (<Wrapper><CreateHygraphModel /></Wrapper>);}
#Resources
- App Framework: Overview to our App Framework, which extends Hygraph capabilities, offering the possibility of creating your own custom apps and sharing them with other users.
- Migrate to apps: A guide on migrating from UIX to app.
- Register an app: Documentation for developers on how to register an app on the Hygraph platform.
- Install an app: Step by step guide on how to install an app in your Hygraph project.
- Delete an app: Documentation for developers on how to delete an app you have created.
- First steps: Comprehensive step-by-step guide on how to develop an app with custom field and sidebar elements.
- Next.js starter: Document that guides you through the process of developing an app with a custom field using our
Next.js
starter. - API Reference: Our App Framework API Reference.