Authentication flow

The default authentication flow employs a client-side PKCE grant. All the details of handling that flow are abstracted as part of the library except mounting a callback handler.

Mounting a callback handler

  1. Add a route for handling the OAuth2 redirect (your redirectUri). This is where your application will redirect on success.

  2. Create the useSignInHandler hook and call it where you want the authentication to be performed. Common places are in the Navigation or your Index route.

import { useFutureverse, UserState } from '@futureverse/react'
import * as React from 'react'

export function useSignInHandler() {
  const { login, authClient } = useFutureverse()

  React.useEffect(() => {
    const userStateChange = (userState: UserState) => {
      if (userState === UserState.SignedIn) {
        // The user has successfully signed in, redirect them somewhere
      }

      if (userState === UserState.SignedOut) {
				// The user is not signed in, so do it
        login()
      }

      if (userState === UserState.SignInFailed) {
				// The sign is failed, either show an error or try again
      }
    }

    authClient.addUserStateListener(userStateChange)
    return () => {
      authClient.removeUserStateListener(userStateChange)
    }
  }, [account, authClient, login, router])
}

Silent authentication

Silent authentication is a process where a user is authenticated without their direct involvement, typically after an initial login, improving the user experience by avoiding unnecessary login prompts.

To enable silent authentication, pass an options object to login function and provide the { silent: true, targetEOA: <ADDRESS OF LOGGED IN USER> } properties.

The silent property should be set to true only if a user wants to renew the session without a login prompt.

Example

import { useFutureverse, UserState } from '@futureverse/react'
import * as React from 'react'
import * as wagmi from 'wagmi'

export const FV_AUTH_SILENT_LOGIN_KEY = 'fvAuthSilentLogin'
export const FV_AUTH_PREV_PATH_KEY = 'fvAuthPrevPath'

function Home() {
  const { login, authClient } = useFutureverse()
  const { address: accountAddress } = wagmi.useAccount()

  React.useEffect(() => {
    const userStateChange = (userState: UserState) => {
      if (userState === UserState.SignedIn) {
        sessionStorage.setItem(FV_AUTH_SILENT_LOGIN_KEY, 'enabled')
        const prevPath = sessionStorage.getItem(FV_AUTH_PREV_PATH_KEY)
        someRedirectFunction(prevPath ?? '/home')
      }
      if (userState === UserState.SignedOut) {
        const silentAuth = sessionStorage.getItem(FV_AUTH_SILENT_LOGIN_KEY)
        const isSilent = silentAuth !== 'disabled'
        if (!isSilent) {
          sessionStorage.setItem(FV_AUTH_PREV_PATH_KEY, router.pathname)
          someRedirectFunction('/')
        }
        login(
          isSilent ? { silent: true, targetEOA: accountAddress ?? null } : undefined
        )
      }
      if (userState === UserState.SignInFailed) {
        someRedirectFunction('/')
        sessionStorage.setItem(FV_AUTH_SILENT_LOGIN_KEY, 'disabled')
        login()
      }
    }
    authClient.addUserStateListener(userStateChange)
    return () => {
      authClient.removeUserStateListener(userStateChange)
    }
  }, [accountAddress, authClient, login])
}

export default Home

Logging in and logging out

With the callback handler mounted, we can now start authenticating our users. Invoking login will display the standard Futureverse login prompt, offering a range of different login methods to the user. Here the user can choose to login/signup using an existing wallet or by letting us create and manage a wallet on their behalf (Coming Soon!).

If you configured the useSignInHandler hook as described above, the log-in modal will pop up automatically if the user is not logged in. login and logout functions from useFutureverse give you fine-grained control over the process.

function FutureverseExperienceDemo() {
  const { login } = useFutureverse()

  return (
    <button
      onClick={() => {
        login()
      }}
    >
      Login!
    </button>
  )
}

Accessing the user session

To access the user session, query the user property on useFutureverse which remains available as long as the user is logged in.

function FutureverseExperienceDemo() {
  const { userSession } = useFutureverse()

  if (userSession != null) {
		return <>You are logged in!</>
	}

  return {
		<>Not logged in</>
	}
}

ID Token

The ID token is a JSON Web Token (JWT) that is issued by identity provider to a client application as part of the user authentication process. The ID token serves as proof of the user's identity and is used by the client application to obtain basic profile information about the user.

The payload of an ID token typically includes a set of claims about the authentication of an end-user by an Authorisation Server.

This table describes the claims that are included in an ID token payload according to the different login types:

Login TypeClaimDescriptionOptional

Custodial and non-Custodial

sub

A locally unique and never reassigned identifier within the Issuer for the End-User

No

Custodial and non-Custodial

eoa

The externally owned account derived from public key

No

Custodial and non-Custodial

futurepass

The FuturePass account address associated with this account

No

Custodial and non-Custodial

chainId

The block chain id

No

Custodial and non-Custodial

nonce

A string value used to associate a Client session with an ID Token, and to mitigate replay attacks

No

Custodial and non-Custodial

at_hash

A hash value verifies the integrity and authenticity of the access token

No

Custodial and non-Custodial

aud

Intended audience for the ID token

No

Custodial and non-Custodial

exp

The expiration time on or after which the ID token MUST NOT be accepted for processing

No

Custodial and non-Custodial

iat

The time at which the ID token was issued

No

Custodial and non-Custodial

iss

The issuer of the response

No

Custodial

auth_time

The time when the authentication occurred

Yes

Custodial and non-Custodial

custodian

self for non-custodial, fv for custodial

No

Custodial (Google and Facebook)

email

When logged in with Google, this is the user's email address. The value of this claim may not be unique to the Google account used to log in, and could change over time.

Yes

When logged in with Facebook, this is the user's primary email address listed on their profile. If there is no valid email address is available, this claim is not included in the ID token.

Because the email may not be present, the experiences should not use this claim as the primary identifier to link to the user’s record.

Last updated

© 2023 -> ♾️