Using Auth0 with Web3Auth
This guide will cover the basics of how to set up your Web3Auth SDK and Auth0 account for the integration and provide you with the links on how to develop a basic web application on the blockchain of your choice.
Quick Start
npx degit Web3Auth/web3auth-pnp-examples/web-no-modal-sdk/custom-authentication/auth0-react-no-modal-example w3a-auth0-demo && cd w3a-auth0-demo && npm install && npm run start
How it works?
- Single Page Applications (SPA) Flow
- Regular Web Applications (RWA) Flow
When integrating Web3Auth with Auth0 SPA the flow looks something like this:
When integrating Web3Auth with Auth0 RWA, we need an additional backend server to communicate with Auth0. The flow looks something like this:
When a user logs in with Auth0, Auth0 sends a JWT
id_token
to the app. This JWT token is sent to the Web3Auth SDK's login function.Finally, on successful validation of the JWT token, Web3Auth SDK will generate a private key for the user, in a self custodial way, resulting in easy onboarding for your user to the application.
Prerequisites
For Web Apps: A basic knowledge of JavaScript is required to use Web3Auth SDK.
For Mobile Apps: For the Web3Auth Mobile SDKs, you have a choice between iOS, Android, React Native & Flutter. Please refer to the Web3Auth SDK Reference for more information.
Create a Web3Auth account on the Web3Auth Dashboard
Create an Auth0 tenant and configure a Single Page Web Application (SPA for Web) or Native (for Mobile) from Auth0 Console.
Please note that Regular Web Applications are also supported as mentioned in the flows above. However for this guide, we’re preferring SPA since its implicit flow doesn’t require an application to host a backend server.
Setup your Auth0 Tenant
Add the following URLs for your app to the Allowed Web Origins field when configuring your Auth0 Application.
- Additional to your own URLs for the application, please add
- https://testing.openlogin.com/auth (for Web3Auth testnet used in demo applications) and
- https://app.openlogin.com/auth (for Web3Auth mainnet used in production applications).
- Additional to your own URLs for the application, please add
You will require
domain
andclientId
of the newly created application which you can copy from Auth0 Console.
Enable Social login
- Enable
Google
or other social provider on theAuthentication > Social
page of your Auth0 Dashboard. - Vist https://auth0.com/learn/social-login to learn more.
Enable SMS Passwordless
If you want to implement SMS Passwordless, then this section is for you. Else you can skip this.
- Enable
SMS
on theAuthentication > Passwordless
page of your Auth0 Dashboard. - Under
Settings
tab, add yourTwilio SID
andTwilio AuthToken
. - Also, update the
From
number on the same page, and click on theSave
button. - Next, enable your application under
Applications
tab, and click on theSave
button. - You can test sending a SMS from the
Try
tab. Once, a SMS comes with OTP, it means it has been successfully configured.
Update Lockscreen for SMS Passwordless
If you're to use SMS Passwordless, please visit here to setup the Lock Screen of Auth0 from your Auth0 Dashboard.
Enable Email Passwordless
If you want to implement Email Passwordless, then this section is for you. Else you can skip this.
- Enable
Email
on theAuthentication > Passwordless
page of your Auth0 Dashboard. - Under
Settings
tab, updateFrom
andSubject
based on your need and click on theSave
button. - Next, enable your application under
Applications
tab, and click on theSave
button. - You can test sending an Email from the
Try
tab. Once, an Email comes with OTP/Link, it means it has been successfully configured.
Update Lockscreen for Email Passwordless
If you're to use Email Passwordless, please visit here to setup the Lock Screen of Auth0 from your Auth0 Dashboard.
Setup your Web3Auth Dashboard
Create a Project from the Project Section of the Web3Auth Developer Dashboard.
Enter your desired Project name.
Select the Product you want to use. For this guide, we'll be using the Plug n Play product.
Select the Platform type you want to use. For this guide, we'll be using the Web Application as the platform.
Select the Web3Auth Network as
Sapphire Devnet
. We recommend creating a project in thesapphire_devnet
ortesnet
network during development. While moving to a production environment, make sure to convert your project tosapphire_mainnet
or any of the legacy mainnet networkmainnet
,aqua
, orcyan
network. Otherwise, you'll end up losing users and keys.Select the blockchain(s) you'll be building this project on. For interoperability with Torus Wallets, you have the option of allowing the user's private key to be used in other applications using Torus Wallets (EVM, Solana, XRPL & Casper).
Finally, once you create the project, you have the option to whitelist your URLs for the project. Please whitelist the domains where your project will be hosted.
Create Auth0 Verifiers
Create a Verifier from the Custom Auth Section of the Developer Dashboard with the following configuration:
- Choose a name of your choice for the verifier identifier.
eg. auth0-project
- Select
Auth0
from the Login Provider. - Choose your Authentication Type from
eg. Google, Twitter, Github etc..
to be the Auth provider. - Paste the
Client ID
andAuth0 Domain
from the Auth0 SPA you created in the above steps. This will be used to validate the JWT token issued by Auth0. - Click on
Create
button to create your verifier. It may take up to 10-20 minutes to deploy verifier on testnet. You'll receive an email once it's complete.
You will require the
verifierName
of the newly created verifier andclientId
of the Plug and Play Project.- Choose a name of your choice for the verifier identifier.
Create SMS Passwordless Verifier
If you want to implement SMS Passwordless, then this section is for you. Else you can skip this.
Create a Verifier from the Custom Auth Section of the Developer Dashboard with the following configuration:
- Choose a name of your choice for the verifier identifier.
eg. auth0-sms-passwordless
- Select
Custom
from the Login Provider. - Choose
Custom
for theJWT Verifier ID
and typename
. - Enter
https://{YOUR-DOMAIN}.auth0.com/.well-known/jwks.json
as yourJWKS Endpoint
. This will be used to validate the JWT token issued by Auth0. - JWT validation fields:
- iss:
https://{YOUR-DOMAIN}.auth0.com
- aud:
{AUTH0-CLIENT-ID}
- iss:
- Click on
Create
button to create your verifier. It may take up to 10-20 minutes to deploy verifier on testnet. You'll receive an email once it's complete.
You will require the
verifierName
of the newly created verifier andclientId
of the Plug and Play Project.- Choose a name of your choice for the verifier identifier.
Create Email Passwordless Verifier
If you want to implement Email Passwordless, then this section is for you. Else you can skip this.
Create a Verifier from the Custom Auth Section of the Developer Dashboard with the following configuration:
- Choose a name of your choice for the verifier identifier.
eg. auth0-email-passwordless
- Select
Auth0
from the Login Provider. - Choose your Authentication Type as
Passwordless
to use Auth0's Email Passwordless. - Paste the
Client ID
andAuth0 Domain
from the Auth0 SPA you created in the above steps. This will be used to validate the JWT token issued by Auth0. - Click on
Create
button to create your verifier. It may take up to 10-20 minutes to deploy verifier on testnet. You'll receive an email once it's complete.
You will require the
verifierName
of the newly created verifier andclientId
of the Plug and Play Project.- Choose a name of your choice for the verifier identifier.
Using the Web3Auth SDK
To use the Web3Auth SDK, you need to add the dependency of the respective platform SDK of Web3Auth to your project. To know more about the available SDKs, please have a look at this documentation page.
For this guide here, we will be talking through the Web3Auth Plug and Play No Modal SDK and using the OpenLogin Provider alongside it to enable Custom Authentication through Auth0.
Setting up your base project for using Web3 libraries:
If you are starting from scratch, to set up this project locally, you will need to create a base Web application, where you can install the required dependencies. However, while working with Web3, there are a few base libraries, which need additional configuration. This is because certain packages are not available in the browser environment, and we need to polyfill them manually. You can follow this documentation where we have mentioned the configuration changes for some popular frameworks for your reference.
Installation
For this project, you need to add the following Web3Auth dependencies to your package.json
npm install --save @web3auth/no-modal @web3auth/openlogin-adapter @web3auth/base web3
Understanding the Dependencies
- Web3Auth Dependencies
- Web3 Libraries
Web3Auth Dependencies
@web3auth/no-modal
This is the main Core package that contains the Web3Auth SDK.
npm install --save @web3auth/no-modal
@web3auth/openlogin-adapter
For using Custom Authentication, we need to use the OpenLogin Adapter, where we can initialise the authentication details.
npm install --save @web3auth/openlogin-adapter
@web3auth/base
Since we're using typescript, we need the @web3auth/base
package to provide types of the different variables we'll be using throughout the app
building process. This reduces errors to a very large extent.
npm install --save @web3auth/base
Web3 Libraries
web3
/ ethers
/ @solana/web3.js
According to your preference, you can choose to install the web3
or ethers
libraries, to talk to the EVM compatible blockchains under the hood.
For Solana, @solana/web3.js
is the recommended choice.
We'll be using web3
for this guide.
npm install --save web3
Initialization
Once installed, your Web3Auth application needs to be initialized. Initialization is a 4 step process where we add all the config details for Web3Auth:
- Instantiation
- Configuration of Adapters
- Configuration of Plugins
- Initialization of the Web3Auth
Please make sure all of this is happening in your application constructor. This makes sure that Web3Auth is initialised when your application starts up.
For this guide, we're only focusing on the Instantiation, Configuration for the Openlogin Adapter (the default adapter that enables social logins) and Initialization of the Web3Auth SDK. To know more about the other things you can do with Web3Auth, checkout our SDK Reference.
Instantiating Web3Auth
Importing the packages
import { WALLET_ADAPTERS, CHAIN_NAMESPACES, IProvider } from "@web3auth/base";
import { Web3AuthNoModal } from "@web3auth/no-modal";
import { OpenloginAdapter } from "@web3auth/openlogin-adapter";
import { EthereumPrivateKeyProvider } from "@web3auth/ethereum-provider";
Alongside the Web3Auth
and OpenloginAdapter
you need the above mentioned packages from @web3auth/base
for different initialisations mentioned
further in this guide.
Instantiate the Web3Auth SDK
import { Web3AuthNoModal } from "@web3auth/no-modal";
import { CHAIN_NAMESPACES } from "@web3auth/base";
const chainConfig = {
chainNamespace: CHAIN_NAMESPACES.EIP155,
chainId: "0x1",
rpcTarget: "https://rpc.ankr.com/eth",
displayName: "Ethereum Mainnet",
blockExplorer: "https://etherscan.io",
ticker: "ETH",
tickerName: "Ethereum",
};
const web3auth = new Web3AuthNoModal({
clientId: "BPi5PB_UiIZ-cPz1GtV5i1I2iOSOHuimiXBI0e-Oe_u6X3oVAbCiAZOTEBtTXw4tsluTITPqA8zMsfxIKMjiqNQ",
web3AuthNetwork: "sapphire_mainnet",
chainConfig,
});
Here, we're using the chainConfig
property to set the chainId and chainNamespace. The chainId
and chainNamespace
are the id and the namespace
respectively of the chain you're connecting to. We've initialized them for EVM for this guide. You can find the list of available providers
here to select from.
Additionally, sometimes you might face clogging in the network, due to the fact that the test network is a bit clogged at that point. To avoid this,
we can use the property rpcTarget
and pass over the URL of the node you want to connect to.
Initialising the Openlogin Adapter
const openloginAdapter = new OpenloginAdapter({
adapterSettings: {
clientId: "YOUR-WEB3AUTH-CLIENT-ID", //Optional - Provide only if you haven't provided it in the Web3Auth Instantiation Code
uxMode: "popup",
loginConfig: {
jwt: {
verifier: "YOUR-VERIFIER-NAME-ON-WEB3AUTH-DASHBOARD",
typeOfLogin: "jwt",
clientId: "YOUR-AUTH0-CLIENT-ID-FROM-AUTH0-DASHBOARD",
},
},
},
});
web3auth.configureAdapter(openloginAdapter);
Here, you need to pass over your Web3Auth clientId
in the adapterSettings object and your Custom Auth verifierName
and Auth0 clientId
in the
loginConfig object. This makes sure that the Openlogin Adapter can connect to the correct verifier and Auth0 server.
Initialising the Web3Auth SDK
await web3auth.init();
Initialising on Mobile Platforms
- For Mobile, depending on the platform, there will be different steps to initialize the SDK. Refer to the respective Mobile SDKs,
Login
Once initialized, you can use the connectTo()
function to authenticate the user when they click the login button.
- Social Logins
- SMS Passwordless Login
- Email Passwordless Login
import { WALLET_ADAPTERS, CHAIN_NAMESPACES } from "@web3auth/base";
await web3auth.connectTo(WALLET_ADAPTERS.OPENLOGIN, {
loginProvider: "jwt",
extraLoginOptions: {
domain: "https://YOUR-AUTH0-DOMAIN", // Please append "https://" before your domain
verifierIdField: "sub", // For SMS & Email Passwordless, use "name" as verifierIdField
},
});
import { WALLET_ADAPTERS, CHAIN_NAMESPACES } from "@web3auth/base";
await web3auth.connectTo(WALLET_ADAPTERS.OPENLOGIN, {
loginProvider: "jwt",
extraLoginOptions: {
domain: "https://YOUR-AUTH0-DOMAIN", // Please append "https://" before your domain
verifierIdField: "name",
},
});
import { WALLET_ADAPTERS, CHAIN_NAMESPACES } from "@web3auth/base";
await web3auth.connectTo(WALLET_ADAPTERS.OPENLOGIN, {
loginProvider: "jwt",
extraLoginOptions: {
domain: "https://YOUR-AUTH0-DOMAIN", // Please append "https://" before your domain
verifierIdField: "name",
},
});
When connecting, your connectTo
function takes the arguments for the adapter you want to connect to and the options for the login. The major thing
to note here is the domain
option in the extraLoginOptions
object. This is the domain of your Auth0 tenant so that you can be redirected to login
there directly from the Web3Auth Plug and Play No Modal SDK.
Get the User Profile
const user = await web3auth.getUserInfo();
console.log("User info", user);
Using the getUserInfo
function, you can get the details of the logged in user. Please note that these details are not stored anywhere in Web3Auth
network, but are fetched from the id_token you received from Auth0 and lives in the frontend context.
Logout
await web3auth.logout();
Logging out your user is as simple as calling the logout
function.
Interacting with the Blockchain
So if you have completed this far, it means that you have successfully authenticated your user. Now, you can use the provider returned by Web3Auth as
web3auth.provider
to interact with your blockchain. You can use the Provider SDKs to perform RPC Calls to your
blockchain.
Web3Auth is chain agnostic, ie. depending on whatever blockchain or layer-2 you use, Web3Auth can easily support that. Web3Auth has native providers
for EVM and Solana blockchains and for others, you can get the private key in the user scope and make RPC calls. For standardising the type of
provider, Web3Auth Base provides a IProvider
from which you can create your own provider.
- Ethereum Provider gives you the capability of making RPC calls to the EVM compatible blockchains.
- Solana Provider gives you the capability of making RPC calls to the Solana blockchain.
- XRPL Provider gives you the capability of making RPC calls to the XRPL blockchain.
- If you want to use any other chain except Solana or EVM chains, for ex: Starknet, you can specify the value of
chainNamespace
field as other in the Web3Auth SDK Constructor. Refer to: Using other blockchains
Get User Accounts
- Web3
- Ethers.js
const getAccounts = async () => {
if (!provider) {
console.log("provider not initialized yet");
return;
}
const web3 = new Web3(provider as any);
const userAccounts = await web3.eth.getAccounts();
console.log(userAccounts);
};
const getAccounts = async () => {
if (!provider) {
console.log("provider not initialized yet");
return;
}
const provider = new ethers.providers.Web3Provider(provider as any);
const signer = provider.getSigner();
const userAccounts = await signer.getAddress();
console.log(userAccounts);
};
View User Balance
- Web3
- Ethers.js
const getBalance = async () => {
if (!provider) {
console.log("provider not initialized yet");
return;
}
const web3 = new Web3(provider as any);
const accounts = await web3.eth.getAccounts();
const balance = await web3.eth.getBalance(accounts[0]);
console.log(web3.utils.fromWei(balance));
};
const getBalance = async () => {
if (!provider) {
console.log("provider not initialized yet");
return;
}
const provider = new ethers.providers.Web3Provider(this.provider as any);
const signer = provider.getSigner();
const account = await signer.getAddress();
// Get user's balance in ether
// For ethers v5
// const balance = ethers.utils.formatEther(
// await ethersProvider.getBalance(address) // Balance is in wei
// );
const balance = ethers.formatEther(
await provider.getBalance(account) // Balance is in wei
);
console.log(balance);
};
Sign Message
- Web3
- Ethers.js
const signMessage = async () => {
if (!provider) {
console.log("provider not initialized yet");
return;
}
const web3 = new Web3(provider as any);
// Get user's Ethereum public address
const account = (await web3.eth.getAccounts())[0];
// Message
const message = "Hello MPC, Bye Bye SeedPhrase";
const typedMessage = [
{
type: "string",
name: "message",
value: message,
},
];
const params = [JSON.stringify(typedMessage), account];
const method = "eth_signTypedData";
const signedMessage = await this.provider.request({
method,
params,
});
console.log(signedMessage);
};
const signMessage = async () => {
if (!provider) {
console.log("provider not initialized yet");
return;
}
const provider = new ethers.providers.Web3Provider(provider);
const signer = provider.getSigner();
const originalMessage = "Hello MPC, Bye Bye SeedPhrase";
const signedMessage = await signer.signMessage(originalMessage);
console.log(signedMessage);
};
Sign Transaction
const signTransaction = async () => {
if (!provider) {
console.log("provider not initialized yet");
return;
}
const web3 = new Web3(provider as any);
const accounts = await web3.eth.getAccounts();
const txRes = await web3.eth.signTransaction({
from: accounts[0],
to: accounts[0],
value: web3.utils.toWei("0.0001"),
chainId: 1, // change it to your specific chain id.
});
console.log(txRes.transactionHash);
};
Send Transaction
- Web3
- Ethers.js
const sendTransaction = async () => {
if (!provider) {
console.log("provider not initialized yet");
return;
}
const web3 = new Web3(provider as any);
const accounts = await web3.eth.getAccounts();
const txRes = await web3.eth.sendTransaction({
from: accounts[0],
to: accounts[0],
value: web3.utils.toWei("0.0001"),
chainId: 1, // change it to your specific chain id.
});
console.log(txRes.transactionHash);
};
const sendTransaction = async () => {
if (!provider) {
console.log("provider not initialized yet");
return;
}
const provider = new ethers.providers.Web3Provider(provider);
const signer = await provider.getSigner();
const address = signer.getAddress();
const tx = await signer.sendTransaction({
to: address,
value: ethers.utils.parseEther("0.0001"),
chainId: 1, // change it to your specific chain id.
});
const receipt = await tx.wait();
console.log(receipt.transactionHash);
};
Additional Reading: Setup Custom Authentication using Auth0 RWA
Difference between SPA and RWA
In the SPA flow, the frontend gets the JWT id_token
from Auth0 directly. This flow is leveraged by the Web3Auth SDK, which handles all the callbacks
by itself and the user just needs to setup the OpenloginAdapter
and connect to the Web3Auth SDK, adding in the Auth0 client_id
in it. Hence, this
is the implicit flow and is the most suitable flow for setting up your authentication via Auth0 and Web3Auth.
In the RWA flow, you have to spin up a server on your own where you'll receive the authorisation code from Auth0. For Web3Auth, still require an
id_token
to be sent to the OpenloginAdapter to log the user in the frontend context. This is where you need to make another call from the backend
server to Auth0 to get the id_token
and pass it over to your frontend where you can send it to the Web3Auth SDK.
Setting up your application with RWA Flow
- In addition to the steps above, setup your Auth0 RWA on dashboard and add callback URLs for both your backend and frontend
- On the frontend, your login button should hit on the following URL
https://{YOUR_DOMAIN_URL}/authorize?scope=openid&response_type=code&client_id={YOUR_AUTH0_CLIENT_ID&redirect_uri={YOUR_BACKEND_SERVER_WHICH_WILL_GET_JWT_TOKEN_FROM_AUTH0}&state=STATE
- This is where the user is redirected to a login screen by Auth0.
- On successful login, the user will be redirected to your backend server with authorization
code
as a query parameter. - In the backend server, you can use the
code
to get theid_token
from Auth0 and redirect the user to the frontend withid_token
as a query parameter
app.get('/callback', (req, res) => {
var options = {
method: 'POST',
url: 'https://{YOUR_DOMAIN_URL}/oauth/token',
headers: { 'content-type': 'application/x-www-form-urlencoded' },
form:{
grant_type: 'authorization_code',
client_id: 'AUTH0_CLIENT_ID',
client_secret: 'AUTH0_CLIENT_SECRET',
code: req.query.code, // the authorisation code you got from auth0
redirect_uri: 'https://{YOUR_FRONTEND_URL}',
scope: "openid profile email"
}
};
var id_token = "";
request(options, function (error, response, data) {
id_token = JSON.parse(data)["id_token"];
redirect_url = "http://{YOUR_FRONTEND_URL}?token=%22+id_token;
// Redirection URL to frontend with `id_token` as a query parameter
res.redirect(redirect_url);
});
})
- In the frontend, pass on this
id_token
to the Web3Auth SDK to authenticate the user
await web3auth.connectTo(WALLET_ADAPTERS.OPENLOGIN, {
loginProvider: "jwt",
extraLoginOptions: {
id_token: "YOUR_ID_TOKEN_FETCHED_FROM_BACKEND_SERVER",
verifierIdField: "sub",
},
});
Try our Demo Application and Example Code
Try our Demo Application with Web3Auth & Auth0 integration. It works for either Ethereum, Solana or Polygon. It also works for both the flows, ie. SPA and RWA. The source code for the demo application is available here.
The code for the application we developed in this guide can be found in the Web3Auth Auth0 Example. Check it out and try running it locally yourself!
Questions?
Ask us on Web3Auth's Community Portal