Authorization Code Grant

Overview

This article describes how to generate access tokens when using an Authorization Code Grant Type. The benefits of this grant type are:

  1. It is more secure. All authentication is routed through your own server, so no session key data is exposed to potential client-side snoopers.

  2. It is more customizable. You can combine data from our APIs and your own and return them together to the user.

  3. This type of authentication can be used to query data about a user without continual user interaction. For example - repeated and cadenced queries of user data.

Example Use Cases

  • An application that periodically checks ownership of an NFT before sending out an email or other notification.

  • An application that combines off-chain data (like health or exercise data from Apple) with on-chain data (like a sports-related NFT the user owns).

  • An application that gives and revokes access to another service based on NFT ownership and periodically re-evaluates ownership.

Getting Started

The first thing you will need to do is create a Developer App of type Authorization Code Grant. This will give you a clientId and clientSecret that can be used to generate access tokens on behalf of your users. You will want to store the clientSecret on your backend server.

This is the general flow that a user will go through when authenticating with your app.

  • User connects their wallet to your website, and signs a message verifying that they own the wallet

  • This signature, along with their wallet address is sent to our auth server, which generates a one-time-use code that can be exchanged for an authorization token.

  • Your client sends that code to your server, which makes a call to our auth server to exchange that for an authorization token.

  • Your server can store that authorization token and refresh when necessary, and now make calls on behalf of the user.

With this flow, you can ask users to authenticate once, and continually call APIs on their behalf on the backend.

Example Implementation

Backend

The Manifold OAuth2.0 endpoint is https://oauth2.manifoldxyz.dev

Here is an example in how to implement the authorization token flow in an Express backend server:

app.get('/token', async (req: any, res: any) => {
  const authCode = req.query.authCode
  const clientId = req.query.clientId
  const signature = req.query.signature
  const address = req.query.address
  const clientSecret = process.env.OAUTH_CLIENT_SECRET

  const response = await fetch('https://oauth2.manifoldxyz.dev/token', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json'
    },
    body: JSON.stringify({
      clientId: clientId,
      code: authCode,
      clientSecret: clientSecret,
      signature: signature
    }),
  })
  
  if (response.status !== 200) {
    // Handle error
    throw new Error();
  }

  const resJson = await response.json()
  /**
   *
   * { access_token: 'abcd', expires_in: 2592000 }
   *
   **/
  
  // Save the JSON locally
  userCredentials[address] = resJson

  res.json({
    authenticated: true
  });
})

Frontend

Now, let's say that your website wants to display all the FVCK_AVATAR// that a user holds. You could set up an endpoint like this:

Note: This npm package is not publicly available yet

import ManifoldClient from '@manifoldxyz/manifold-data-client'

app.get('/avatars', async (req: any, res: any) => {
  const address = req.query.address

  const manifoldClient = new ManifoldClient({ token: userCredentials[address].access_token })

  const data = await manifoldClient.getNFTsOfOwner({
    filters: [
      {
        contractAddress: '0x10cdcb5a80e888ec9e9154439e86b911f684da7b'
      }
    ]
  })
  
  res.json(data)
})

Last updated