> For the complete documentation index, see [llms.txt](/llms.txt).

# Custom authentication

Custom authentication is a way to authenticate users with your custom authentication service. For example, while authenticating with Google, you can use your own Google Client ID to authenticate users directly.

This feature, with Multi-Factor Authentication (MFA) turned off, can make Embedded Wallets invisible to the end user.

note

This is a paid feature and the minimum [pricing plan](https://web3auth.io/pricing.html) to use this SDK in a production environment is the **Growth Plan**. You can use this feature in Web3Auth Sapphire Devnet network for free.

## Getting an Auth Connection ID[​](#getting-an-auth-connection-id "Direct link to Getting an Auth Connection ID")

prerequisite

To enable this, you need to [create a connection](/embedded-wallets/dashboard/authentication/) from the **Authentication** tab of your project from the [Embedded Wallets developer dashboard](https://developer.metamask.io) with your desired configuration.

To configure a connection, you need to provide the particular details of the connection into our Embedded Wallets dashboard. This enables us to map a `authConnectionId` with your connection details. This `authConnectionId` helps us to identify the connection details while initializing the SDK. You can configure multiple connections for the same project, and you can also update the connection details anytime.

tip

Learn more about the [auth provider setup](/embedded-wallets/authentication/) and the different configurations available for each connection.

## Modal custom authentication[​](#modal-custom-authentication "Direct link to Modal custom authentication")

The basic custom authentication is available directly in the modal. You can configure each of the auth providers in the modal to direct to your `authConnectionId`.

note

You can only configure implicit login via modal, for JWT-based logins, you need to create your own UI and use the `connectTo` function.

For the modal custom authentication, you need to pass the `modalConfig` object to the `Web3AuthOptions` object within the constructor.

tip

Read more about the `modalConfig` object in the [Whitelabel](/embedded-wallets/sdk/react/advanced/whitelabel/) section.

### Usage[​](#usage "Direct link to Usage")

- Single connections
- Grouped connections

web3authContext.tsx

```
import { WALLET_CONNECTORS, WEB3AUTH_NETWORK } from '@web3auth/modal'
import { type Web3AuthContextConfig } from '@web3auth/modal/react'

const web3AuthContextConfig: Web3AuthContextConfig = {
  web3AuthOptions: {
    clientId: 'YOUR_WEB3AUTH_CLIENT_ID', // Pass your Web3Auth Client ID, ideally using an environment variable
    web3AuthNetwork: WEB3AUTH_NETWORK.SAPPHIRE_MAINNET,
    modalConfig: {
      connectors: {
        [WALLET_CONNECTORS.AUTH]: {
          label: 'auth',
          loginMethods: {
            google: {
              name: 'google login',
              authConnectionId: 'w3a-google-demo',
            },
            facebook: {
              name: 'facebook login',
              authConnectionId: 'w3a-facebook-demo',
            },
            discord: {
              name: 'discord login',
              authConnectionId: 'w3a-discord-demo',
            },
            twitch: {
              name: 'twitch login',
              authConnectionId: 'w3a-twitch-demo',
            },
            twitter: {
              name: 'twitter login',
              // it will hide the twitter option from the Web3Auth modal.
              showOnModal: false,
            },
            email_passwordless: {
              name: 'email passwordless login',
              authConnectionId: 'w3a-email_passwordless-demo',
            },
            sms_passwordless: {
              name: 'sms passwordless login',
              authConnectionId: 'w3a-sms_passwordless-demo',
            },
          },
          // setting it to false will hide all social login methods from modal.
          showOnModal: true,
        },
      },
    },
  },
}

export default web3AuthContextConfig

```

web3authContext.tsx

```
import { WALLET_CONNECTORS, WEB3AUTH_NETWORK } from '@web3auth/modal'
import { type Web3AuthContextConfig } from '@web3auth/modal/react'

const web3AuthContextConfig: Web3AuthContextConfig = {
  web3AuthOptions: {
    clientId: 'YOUR_WEB3AUTH_CLIENT_ID', // Pass your Web3Auth Client ID, ideally using an environment variable
    web3AuthNetwork: WEB3AUTH_NETWORK.SAPPHIRE_MAINNET,
    modalConfig: {
      connectors: {
        [WALLET_CONNECTORS.AUTH]: {
          label: 'auth',
          loginMethods: {
            google: {
              name: 'google login',
              authConnectionId: 'w3a-google',
              groupedAuthConnectionId: 'aggregate-sapphire',
            },
            facebook: {
              name: 'facebook login',
              authConnectionId: 'w3a-facebook',
              groupedAuthConnectionId: 'aggregate-sapphire',
            },
            email_passwordless: {
              name: 'email passwordless login',
              authConnectionId: 'w3a-email-passwordless',
              groupedAuthConnectionId: 'aggregate-sapphire',
            },
          },
        },
      },
    },
  },
}

export default web3AuthContextConfig

```

## Advanced custom authentication[​](#advanced-custom-authentication "Direct link to Advanced custom authentication")

The more advanced custom authentication is available via the `connectTo` function. This allows you to any service you want and tie it to your Web3Auth Integration. **This method allows you to make Web3Auth totally invisible to your end users and have a fully whitelabeled experience all across.**

You can utilise this function to enable multiple types of connections like:

- Implicit login connections
- JWT login connections
- Grouped auth connections

<details>
<summary>`connectTo` Function Reference</summary>

```
connectTo<T extends WALLET_CONNECTOR_TYPE>(
  connector: T,
  params?: LoginParamMap[T]
): Promise<IProvider | null>;

export type LoginParamMap = {
    [WALLET_CONNECTORS.AUTH]: Partial<AuthLoginParams>;
    ...
};

```

#### `AuthLoginParams`[​](#authloginparams "Direct link to authloginparams")

- Table
- Interface

| Parameter                | Description                                                                                                                      |
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------- |
| loginHint?               | Helps pass over the login hint to the auth provider. This is used especially for email_passwordless and sms_passwordless logins. |
| idToken?                 | Pass over the JWT ID token directly to Web3Auth for JWT authentication.                                                          |
| authConnection?          | The auth provider to use for login (for example, "google", "facebook").                                                          |
| authConnectionId?        | The ID configured in your Embedded Wallets dashboard for the connection.                                                         |
| groupedAuthConnectionId? | The grouped Auth Connection ID to be used for login.                                                                             |
| extraLoginOptions?       | Custom OAuth options (for example, login_hint, domain).                                                                          |

```
export type AuthLoginParams = LoginParams & {
  loginHint?: string;
  idToken?: string;
};
export type LoginParams = {
/**
* Any custom state you wish to pass along. This will be returned to you post redirect.
* Use this to store data that you want to be available to the dapp after login.
*/
appState?: string;
/**
* The auth connection to be used for login.
*/
authConnection: AUTH_CONNECTION_TYPE | CUSTOM_AUTH_CONNECTION_TYPE;
/**
* The auth connection ID to be used for login.
*/
authConnectionId?: string;
/**
* The grouped auth connection ID to be used for login.
*/
groupedAuthConnectionId?: string;
/**
* You can set the `mfaLevel` to customize when mfa screen should be shown to user.
* It currently accepts 4 values:-
* - `'default'`: Setting mfa level to `default` will present mfa screen to user on every third login.
* - `'optional'`: Setting mfa level to `default` will present mfa screen to user on every login but user can skip it.
* - `'mandatory'`: Setting mfa level to `mandatory` will make it mandatory for user to setup mfa after login.
* - `'none'`: Setting mfa level to `none` will make the user skip the mfa setup screen
*
* Defaults to `none`
* @defaultValue `none`
*/
mfaLevel?: MfaLevelType;
/**
* This option is for internal use only in torus wallet and has no effect
* on user's login on other dapps.
*
* Defaults to false
* @defaultValue false
* @internal
*/
getWalletKey?: boolean;
/**
* extraLoginOptions can be used to pass standard oauth login options to
* loginProvider.
*
* For ex: you will have to pass `login_hint` as user's email and `domain`
* as your app domain in `extraLoginOptions` while using `email_passwordless`
* loginProvider
*/
extraLoginOptions?: ExtraLoginOptions;
/**
* Custom Logins can get a dapp share returned to them post successful login.
* This is useful if the dapps want to use this share to allow users to login seamlessly
* dappShare is a 24 word seed phrase
*/
dappShare?: string;
/**
* This curve will be used to determine the public key encoded in the jwt token which returned in
* `getUserInfo` function after user login.
* You can use that public key from jwt token as a unique user identifier in your backend.
*
* - `'secp256k1'`: secp256k1 based pub key is added as a wallet public key in jwt token to use.
* - `'ed25519'`: ed25519 based pub key is added as a wallet public key in jwt token to use.
*
* Note: This parameter won't change format of private key returned by auth. Private key returned
* by auth is always `secp256k1`.
*
*
* @defaultValue secp256k1
*/
curve?: SUPPORTED_KEY_CURVES_TYPE;
/**
* Allows the dapp to set a custom redirect url for the manage mfa flow.
*
*/
dappUrl?: string;
};

```

#### Auth connection types[​](#auth-connection-types "Direct link to Auth connection types")

```
export const AUTH_CONNECTION = {
  GOOGLE: 'google',
  TWITTER: 'twitter',
  FACEBOOK: 'facebook',
  DISCORD: 'discord',
  FARCASTER: 'farcaster',
  APPLE: 'apple',
  GITHUB: 'github',
  REDDIT: 'reddit',
  LINE: 'line',
  KAKAO: 'kakao',
  LINKEDIN: 'linkedin',
  TWITCH: 'twitch',
  TELEGRAM: 'telegram',
  WECHAT: 'wechat',
  EMAIL_PASSWORDLESS: 'email_passwordless',
  SMS_PASSWORDLESS: 'sms_passwordless',
  CUSTOM: 'custom',
}

```

#### Advanced options (`extraLoginOptions`)[​](#advanced-options-extraloginoptions "Direct link to advanced-options-extraloginoptions")

For custom integrations (like Auth0, AWS Cognito), you can provide additional options:

- Table
- Interface

| Parameter             | Description                                                 |
| --------------------- | ----------------------------------------------------------- |
| isUserIdCaseSensitive | Whether the user ID field is case sensitive [Default: true] |
| domain                | Auth provider domain (for example, "example.auth0.com")     |
| client_id             | Client ID from your auth provider                           |
| scope                 | OAuth scopes (for example, "email profile openid")          |
| response_type         | Response type for OAuth flow                                |
| login_hint            | Pre-fill user identifier                                    |

```
export type ExtraLoginOptions = Auth0ClientOptions;

export interface Auth0ClientOptions extends BaseLoginOptions {
/**
 * Your Auth0 account domain such as `'example.auth0.com'`,
 * `'example.eu.auth0.com'` or , `'example.mycompany.com'`
 * (when using [custom domains](https://auth0.com/docs/custom-domains))
 */
domain?: string;
/**
 * The Client ID found on your Application settings page
 */
client_id?: string;
/**
 * The field in jwt token which maps to user id
 */
userIdField?: string;
/**
 * Whether the user ID field is case sensitive
 * @defaultValue true
 */
isUserIdCaseSensitive?: boolean;
id_token?: string;
access_token?: string;
/**
 * The route for user info endpoint. This will be padded to domain
 * @defaultValue userinfo
 * */
user_info_route?: string;
/**
 * The flow type for email_passwordless login
 */
flow_type?: EMAIL_FLOW_TYPE;
}

```


</details>

### Implicit logins[​](#implicit-logins "Direct link to Implicit logins")

Implicit logins are the easiest way to authenticate users with your custom authentication services. Web3Auth currently supports implicit logins for the following providers directly:

- Google
- Facebook
- Discord
- Twitch
- Auth0 (custom)

In addition to these you can also use any other provider (for example, Auth0, AWS Cognito, Azure AD) by providing the particular details of their login within the `extraLoginOptions` object within the `connectTo` function.

#### Usage[​](#usage-1 "Direct link to Usage")

- Google
- Facebook
- Discord
- Twitch
- Auth0 Google
- Auth0 SPA
- AWS Cognito

web3authContext.tsx

```
await connectTo(WALLET_CONNECTORS.AUTH, {
  authConnection: AUTH_CONNECTION.GOOGLE,
  authConnectionId: 'w3a-google-demo',
})

```

web3authContext.tsx

```
await connectTo(WALLET_CONNECTORS.AUTH, {
  authConnection: AUTH_CONNECTION.FACEBOOK,
  authConnectionId: 'w3a-facebook-demo',
})

```

web3authContext.tsx

```
await connectTo(WALLET_CONNECTORS.AUTH, {
  authConnection: AUTH_CONNECTION.DISCORD,
  authConnectionId: 'w3a-discord-demo',
})

```

web3authContext.tsx

```
await connectTo(WALLET_CONNECTORS.AUTH, {
  authConnection: AUTH_CONNECTION.TWITCH,
  authConnectionId: 'w3a-twitch-demo',
})

```

web3authContext.tsx

```
await connectTo(WALLET_CONNECTORS.AUTH, {
  authConnection: AUTH_CONNECTION.CUSTOM,
  authConnectionId: 'w3a-auth0-demo',
  extraLoginOptions: {
    connection: 'google-oauth2',
  },
})

```

web3authContext.tsx

```
await connectTo(WALLET_CONNECTORS.AUTH, {
  authConnection: AUTH_CONNECTION.CUSTOM,
  authConnectionId: 'w3a-auth0-demo',
})

```

web3authContext.tsx

```
await connectTo(WALLET_CONNECTORS.AUTH, {
  authConnection: AUTH_CONNECTION.CUSTOM,
  authConnectionId: 'w3a-cognito-demo',
  extraLoginOptions: {
    clientId: import.meta.env.VITE_COGNITO_CLIENT_ID,
    domain: 'https://shahbaz-web3auth.auth.ap-south-1.amazoncognito.com',
    verifierIdField: 'email',
    response_type: 'token',
    scope: 'email profile openid',
  },
})

```

### JWT login[​](#jwt-login "Direct link to JWT login")

JWT login is a way to authenticate users with your custom authentication services. With this method, Web3Auth just takes into account the `idToken` passed over to the `connectTo` function and uses it to authenticate the user. You can utilise this method with any authentication service that is OAuth 2.0 Compatible.

warning

If you have not configured on the dashboard, whether you user ID is case sensitive or not, then you need to pass the `isUserIdCaseSensitive` option to the `extraLoginOptions`.

#### Usage[​](#usage-2 "Direct link to Usage")

- Google One Tap
- Auth0 JWT login
- Firebase JWT login
- Custom JWT login

App.tsx

```
const loginWithGoogle = async (response: CredentialResponse) => {
  const idToken = response.credential;

  await connectTo(WALLET_CONNECTORS.AUTH, {
    authConnectionId: "w3a-google-demo",
    authConnection: AUTH_CONNECTION.GOOGLE,
    idToken,
    extraLoginOptions: {
      isUserIdCaseSensitive: false,
    },
  });
};

...

<GoogleLogin
  onSuccess={loginWithGoogle}
  onError={() => {
    console.log("Login Failed");
  }}
  useOneTap
/>

```

App.tsx

```
const { getIdTokenClaims, loginWithPopup } = useAuth0()

const loginWithAuth0 = async () => {
  try {
    await loginWithPopup()

    const idToken = (await getIdTokenClaims())?.__raw.toString()
    if (!idToken) {
      throw new Error('No id token found')
    }

    await connectTo(WALLET_CONNECTORS.AUTH, {
      authConnectionId: 'w3a-auth0-demo',
      authConnection: AUTH_CONNECTION.CUSTOM,
      idToken,
      extraLoginOptions: {
        isUserIdCaseSensitive: false,
      },
    })
  } catch (err) {
    console.error(err)
  }
}

```

App.tsx

```
const loginWithFirebaseGithub = async () => {
  try {
    const app = initializeApp(firebaseConfig)
    const auth = getAuth(app)
    const githubProvider = new GithubAuthProvider()

    const result = await signInWithPopup(auth, githubProvider)

    const idToken = await result.user.getIdToken(true)

    connectTo(WALLET_CONNECTORS.AUTH, {
      authConnectionId: 'w3a-firebase-demo',
      authConnection: AUTH_CONNECTION.CUSTOM,
      idToken,
      extraLoginOptions: {
        isUserIdCaseSensitive: false,
      },
    })
  } catch (error) {
    console.error('Firebase authentication error:', error)
  }
}

```

App.tsx

```
const getIdToken = async () => {
  // Get id token from server
  const res = await fetch('http://localhost:8080/api/token', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
  })
  const data = await res.json()
  return data?.token
}

const loginWithJWT = async () => {
  try {
    const idToken = await getIdToken()

    await connectTo(WALLET_CONNECTORS.AUTH, {
      authConnection: AUTH_CONNECTION.CUSTOM,
      authConnectionId: 'w3a-node-demo',
      idToken,
      extraLoginOptions: {
        isUserIdCaseSensitive: false,
      },
    })
  } catch (err) {
    console.error(err)
  }
}

```

### Grouped auth connections[​](#grouped-auth-connections "Direct link to Grouped auth connections")

Grouped auth connections allows you to group multiple auth connections together and use them as a single connection. This is useful when you want to authenticate the user with multiple providers and require the same user wallet address to be generated.

For example, you can group Google and email passwordless providers together and use them as a single connection. Now, if your user logs in with Google Auth or even with email passwordless using the same email, they will get the same wallet address.

Prerequisites

You need to configure a grouped connection, by combining your single connections in the Embedded Wallets dashboard before using this feature.

- Google [Implicit] + Auth0 [Implicit]
- Google One Tap [JWT] + Auth0 [JWT]
- Google [Implicit] + Firebase [JWT]

App.tsx

```
const loginWithGoogle = async () => {
  await connectTo(WALLET_CONNECTORS.AUTH, {
    groupedAuthConnectionId: 'aggregate-sapphire',
    authConnectionId: 'w3a-google',
    authConnection: AUTH_CONNECTION.GOOGLE,
  })
}

const loginWithAuth0Google = async () => {
  await connectTo(WALLET_CONNECTORS.AUTH, {
    groupedAuthConnectionId: 'aggregate-sapphire',
    authConnectionId: 'w3a-a0-google',
    authConnection: AUTH_CONNECTION.CUSTOM,
    extraLoginOptions: {
      connection: 'google-oauth2',
    },
  })
}

const loginWithAuth0GitHub = async () => {
  await connectTo(WALLET_CONNECTORS.AUTH, {
    groupedAuthConnectionId: 'aggregate-sapphire',
    authConnectionId: 'w3a-a0-github',
    authConnection: AUTH_CONNECTION.CUSTOM,
    extraLoginOptions: {
      connection: 'github',
    },
  })
}

```

App.tsx

```
const loginWithGoogle = async (response: CredentialResponse) => {
  const idToken = response.credential

  await connectTo(WALLET_CONNECTORS.AUTH, {
    groupedAuthConnectionId: 'aggregate-sapphire',
    authConnectionId: 'w3a-google',
    authConnection: AUTH_CONNECTION.GOOGLE,
    idToken,
    extraLoginOptions: {
      isUserIdCaseSensitive: false,
      verifierIdField: 'email',
    },
  })
}

const loginWithAuth0 = async () => {
  try {
    await loginWithPopup()
    const idToken = (await getIdTokenClaims())?.__raw.toString()
    if (!idToken) {
      throw new Error('No id token found')
    }

    await connectTo(WALLET_CONNECTORS.AUTH, {
      groupedAuthConnectionId: 'aggregate-sapphire',
      authConnectionId: 'w3a-a0-github',
      authConnection: AUTH_CONNECTION.CUSTOM,
      idToken,
      extraLoginOptions: {
        isUserIdCaseSensitive: false,
        verifierIdField: 'email',
      },
    })
  } catch (err) {
    console.error(err)
  }
}

```

App.tsx

```
const loginWithGoogle = async () => {
  await connectTo(WALLET_CONNECTORS.AUTH, {
    groupedAuthConnectionId: 'aggregate-sapphire',
    authConnectionId: 'w3a-google',
    authConnection: AUTH_CONNECTION.GOOGLE,
  })
}

const loginWithFirebaseGithub = async () => {
  const app = initializeApp(firebaseConfig)
  const auth = getAuth(app)
  const githubProvider = new GithubAuthProvider()

  const result = await signInWithPopup(auth, githubProvider)

  const idToken = await result.user.getIdToken(true)

  connectTo(WALLET_CONNECTORS.AUTH, {
    groupedAuthConnectionId: 'aggregate-sapphire',
    authConnectionId: 'w3a-firebase',
    authConnection: AUTH_CONNECTION.CUSTOM,
    idToken,
    extraLoginOptions: {
      isUserIdCaseSensitive: false,
    },
  })
}

```
