Web3 Session with NextAuth.js
In a decentralized application, a user is often identified by a Cryptocurrency wallet such as Metamask. However, since Metamask works by injecting a script into the page, it is only available on the client, cutting off the ability to use getServerSideProps
to fetch user data.
We can solve this by pairing a NextAuth.js session with a convenient hooks library called WAGMI. We will need to configure NextAuth.js with the CredentialsProvider
:
import NextAuth from 'next-auth' import { utils } from 'ethers' import CredentialsProvider from 'next-auth/providers/credentials' export default NextAuth({ providers: [ CredentialsProvider({ name: 'Credentials', credentials: { address: { label: 'Address', type: 'text', placeholder: '0x0', }, }, async authorize(credentials) { if (Boolean(utils.getAddress(credentials?.address!))) { return null } return { id: credentials?.address, } }, }), ], session: { strategy: 'jwt', }, jwt: { secret: process.env.JWT_SECRET, }, callbacks: { async session({ session, token }) { session.address = token.sub return session }, }, secret: process.env.NEXT_AUTH_SECRET, pages: { signIn: '/', signOut: '/', error: '/', newUser: '/', }, })
Doing this will allow us to login users with a session:
// NextAuth.js signIn will help us create a session import { signIn } from 'next-auth/react' // hooks that allow to use metamask informations import { useConnect, useAccount } from 'wagmi' Function Login(){ const [{ data: connectData }, connect] = useConnect() const [{ data: accountData }] = useAccount() const handleLogin = async () => { try { const callbackUrl = '/protected' if (accountData?.address) { signIn('credentials', { address: accountData.address, callbackUrl }) return } const { data, error } = await connect(connectData.connectors[0]) if (error) { throw error } signIn('credentials', { address: data?.account, callbackUrl }) } catch (error) { window.alert(error) } } ... rest of your component
Please install Metamask to use this example.