How to Authenticate Users with Web3Auth
What is Web3Auth?
info
Visit Web3Auth docs to get more information.
Web3Auth is a pluggable auth infrastructure for Web3 wallets and applications. It streamlines the onboarding of mainstream and crypto-native users in under a minute by providing experiences they're most comfortable with. With support for all social logins, web and mobile-native platforms, wallets, and other key management methods, Web3Auth results in a standard cryptographic key provider specific to the user and application.
Before Starting
You can start this tutorial if you already have a NextJS dapp with MetaMask sign-in functionality.
Installing the Web3Auth Wagmi Connector
Install the @web3auth/web3auth-wagmi-connector
dependency:
- npm
- Yarn
npm install @web3auth/web3auth-wagmi-connector
yarn add @web3auth/web3auth-wagmi-connector
Configuring the Web3Auth Wagmi Connector
- Open the
pages/signin.jsx
file and addWeb3AuthConnector
as a connector to theuseConnect()
hook:
import { Web3AuthConnector } from '@web3auth/web3auth-wagmi-connector'
import { signIn } from 'next-auth/react'
import { useAccount, useConnect, useSignMessage, useDisconnect } from 'wagmi'
import { useRouter } from 'next/router'
import axios from 'axios'
function SignIn() {
const { connectAsync } = useConnect({
connector: new Web3AuthConnector({
options: {
enableLogging: true,
clientId: 'YOUR_CLIENT_ID', // Get your own client id from https://dashboard.web3auth.io
network: 'testnet', // web3auth network
chainId: '0x1', // chainId that you want to connect with
},
}),
})
const { disconnectAsync } = useDisconnect()
const { isConnected } = useAccount()
const { signMessageAsync } = useSignMessage()
const { push } = useRouter()
const handleAuth = async () => {
if (isConnected) {
await disconnectAsync()
}
const { account } = await connectAsync()
const userData = { address: account, chain: '0x1', network: 'evm' }
const { data } = await axios.post('/api/auth/request-message', userData, {
headers: {
'Content-Type': 'application/json',
},
})
const message = data.message
const signature = await signMessageAsync({ message })
// redirect user after success authentication to '/user' page
const { url } = await signIn('credentials', {
message,
signature,
redirect: false,
callbackUrl: '/user',
})
/**
* instead of using signIn(..., redirect: "/user")
* we get the url from callback and push it to the router to avoid page refreshing
*/
push(url)
}
return (
<div>
<h3>Web3 Authentication</h3>
<button onClick={() => handleAuth()}>Authenticate via Web3Auth</button>
</div>
)
}
export default SignIn
Testing the Web3Auth Connector
Visit http://localhost:3000/signin
to test authentication.
- Click on
Authenticate via Web3Auth
:
- Select the preferred sign-in method:
- After successful authentication, you will be redirected to the
/user
page:
- Visit
http://localhost:3000/user
to test the user session's functionality:
- When a user is authenticated, we show the user's info on the page.
- When a user is not authenticated, we redirect to the
/signin
page. - When a user is authenticated, we show the user's info on the page, even refreshing after the page. (Explanation: After Web3 wallet authentication, the
next-auth
library creates a session cookie with an encrypted JWT [JWE] stored inside. It contains session info [such as an address and signed message] in the user's browser.)