| title | Custom authentication |
|---|---|
| sidebar_label | Custom authentication |
| description | @web3auth/modal Custom Authentication | Embedded Wallets |
import Tabs from '@theme/Tabs' import TabItem from '@theme/TabItem' import GrowthPlanNote from '../../_common/_growth_plan_note.mdx'
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 MFA turned off, can make Embedded Wallets invisible to the end user.
:::info prerequisite
To enable this, you need to create a connection from the Authentication tab of your project from the Embedded Wallets developer dashboard 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 and the different configurations available for each connection.
:::
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
Learn more about the modalConfig object in the Whitelabel section.
:::
import { WALLET_CONNECTORS, WEB3AUTH_NETWORK } from '@web3auth/modal'
import { type Web3AuthContextConfig } from '@web3auth/modal/vue'
const web3AuthContextConfig: Web3AuthContextConfig = {
web3AuthOptions: {
clientId: 'YOUR_WEB3AUTH_CLIENT_ID', // Pass your Web3Auth Client ID, ideally using an environment variable
web3AuthNetwork: WEB3AUTH_NETWORK.SAPPHIRE_MAINNET,
// focus-start
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,
},
},
},
// focus-end
},
}
export default web3AuthContextConfigimport { WALLET_CONNECTORS, WEB3AUTH_NETWORK } from '@web3auth/modal'
import { type Web3AuthContextConfig } from '@web3auth/modal/vue'
const web3AuthContextConfig: Web3AuthContextConfig = {
web3AuthOptions: {
clientId: 'YOUR_WEB3AUTH_CLIENT_ID', // Pass your Web3Auth Client ID, ideally using an environment variable
web3AuthNetwork: WEB3AUTH_NETWORK.SAPPHIRE_MAINNET,
// focus-start
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',
},
},
},
},
},
// focus-end
},
}
export default web3AuthContextConfigThe 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
`connectTo` Function Reference
connectTo<T extends WALLET_CONNECTOR_TYPE>(
connector: T,
params?: LoginParamMap[T]
): Promise<Connection | null>;
export type LoginParamMap = {
[WALLET_CONNECTORS.AUTH]: Partial<AuthLoginParams>;
...
};| 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 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',
}For custom integrations (like Auth0, AWS Cognito), you can provide additional options:
| 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 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;
}
```
Implicit logins are the easiest way to authenticate users with your custom authentication services. Web3Auth currently supports implicit logins for the following providers directly:
- 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.
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.
:::
const loginWithGoogle = async (idToken: string) => {
// focus-start
await connectTo(WALLET_CONNECTORS.AUTH, {
authConnectionId: 'w3a-google-demo',
authConnection: AUTH_CONNECTION.GOOGLE,
idToken,
extraLoginOptions: {
isUserIdCaseSensitive: false,
},
})
// focus-end
}<script setup lang="ts">
import { WALLET_CONNECTORS, AUTH_CONNECTION } from '@web3auth/modal'
import { useWeb3AuthConnect } from '@web3auth/modal/vue'
import { Auth0Client } from '@auth0/auth0-spa-js'
const { connectTo } = useWeb3AuthConnect()
const auth0Client = new Auth0Client({
domain: 'YOUR_AUTH0_DOMAIN',
clientId: 'YOUR_AUTH0_CLIENT_ID',
authorizationParams: {
redirect_uri: window.location.origin,
},
})
const loginWithAuth0 = async () => {
await auth0Client.loginWithPopup()
const idToken = await auth0Client.getIdTokenClaims()
// focus-start
await connectTo(WALLET_CONNECTORS.AUTH, {
authConnectionId: 'w3a-auth0-demo',
authConnection: AUTH_CONNECTION.CUSTOM,
idToken: idToken.__raw,
extraLoginOptions: {
isUserIdCaseSensitive: false,
},
})
// focus-end
}
</script>
<template>
<button @click="loginWithAuth0">Login with Auth0</button>
</template>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)
// focus-start
connectTo(WALLET_CONNECTORS.AUTH, {
authConnectionId: 'w3a-firebase-demo',
authConnection: AUTH_CONNECTION.CUSTOM,
idToken,
extraLoginOptions: {
isUserIdCaseSensitive: false,
},
})
// focus-end
} catch (error) {
console.error('Firebase authentication error:', error)
}
}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()
// focus-start
await connectTo(WALLET_CONNECTORS.AUTH, {
authConnection: AUTH_CONNECTION.CUSTOM,
authConnectionId: 'w3a-node-demo',
idToken,
extraLoginOptions: {
isUserIdCaseSensitive: false,
},
})
// focus-end
} catch (err) {
console.error(err)
}
}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.
:::info Prerequisites
You need to configure a grouped connection, by combining your single connections in the Embedded Wallets dashboard before using this feature.
:::
const loginWithGoogle = async () => {
// focus-start
await connectTo(WALLET_CONNECTORS.AUTH, {
groupedAuthConnectionId: 'aggregate-sapphire',
authConnectionId: 'w3a-google',
authConnection: AUTH_CONNECTION.GOOGLE,
})
// focus-end
}
const loginWithAuth0Google = async () => {
// focus-start
await connectTo(WALLET_CONNECTORS.AUTH, {
groupedAuthConnectionId: 'aggregate-sapphire',
authConnectionId: 'w3a-a0-google',
authConnection: AUTH_CONNECTION.CUSTOM,
extraLoginOptions: {
connection: 'google-oauth2',
},
})
// focus-end
}
const loginWithAuth0GitHub = async () => {
// focus-start
await connectTo(WALLET_CONNECTORS.AUTH, {
groupedAuthConnectionId: 'aggregate-sapphire',
authConnectionId: 'w3a-a0-github',
authConnection: AUTH_CONNECTION.CUSTOM,
extraLoginOptions: {
connection: 'github',
},
})
// focus-end
}import { Auth0Client } from '@auth0/auth0-spa-js'
const { connectTo } = useWeb3AuthConnect()
const loginWithGoogle = async (idToken: string) => {
// focus-start
await connectTo(WALLET_CONNECTORS.AUTH, {
groupedAuthConnectionId: 'aggregate-sapphire',
authConnectionId: 'w3a-google',
authConnection: AUTH_CONNECTION.GOOGLE,
idToken,
extraLoginOptions: {
isUserIdCaseSensitive: false,
verifierIdField: 'email',
},
})
// focus-end
}
const auth0Client = new Auth0Client({
domain: 'YOUR_AUTH0_DOMAIN',
clientId: 'YOUR_AUTH0_CLIENT_ID',
authorizationParams: {
redirect_uri: window.location.origin,
},
})
const loginWithAuth0 = async () => {
try {
await auth0Client.loginWithPopup()
const idToken = (await getIdTokenClaims())?.__raw.toString()
if (!idToken) {
throw new Error('No id token found')
}
// focus-start
await connectTo(WALLET_CONNECTORS.AUTH, {
groupedAuthConnectionId: 'aggregate-sapphire',
authConnectionId: 'w3a-a0-github',
authConnection: AUTH_CONNECTION.CUSTOM,
idToken,
extraLoginOptions: {
isUserIdCaseSensitive: false,
verifierIdField: 'email',
},
})
// focus-end
} catch (err) {
console.error(err)
}
}const loginWithGoogle = async () => {
// focus-start
await connectTo(WALLET_CONNECTORS.AUTH, {
groupedAuthConnectionId: 'aggregate-sapphire',
authConnectionId: 'w3a-google',
authConnection: AUTH_CONNECTION.GOOGLE,
})
// focus-end
}
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)
// focus-start
connectTo(WALLET_CONNECTORS.AUTH, {
groupedAuthConnectionId: 'aggregate-sapphire',
authConnectionId: 'w3a-firebase',
authConnection: AUTH_CONNECTION.CUSTOM,
idToken,
extraLoginOptions: {
isUserIdCaseSensitive: false,
},
})
// focus-end
}