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.