User Authentication (SIWE)
You may need to know a user’s wallet address on the server-side, for use cases such as token-gated pages or signature-based minting.
Providing the user’s wallet address from the client is not secure, as it can be spoofed. Instead, the EIP-4361 Sign in with Ethereum (SIWE) standard can be used to ask the user to prove ownership of their wallet address by signing a message, and then verifying the signature on the server-side.
EVM Kit uses thirdweb Auth to provide this SIWE functionality, which uses a 3-step process:
- Server generates a message for the user to sign (message follows SIWE standard).
- User signs the message with their wallet, proving ownership of the wallet address.
- Server verifies the signature and the user enters authenticated state.
Since we are using Next.js, the client and server are both in the /application
directory.
The app comes with a UserAuthentication component to showcase the SIWE flow and access of restricted server-side data.
Configuration
Two environment variables can be set in .env
to configure the SIWE flow:
Generating Messages
The Connect Wallet Button
comes with an auth
prop, that can be used to showcase a “Sign In” state after the user connects their wallet.
When the user clicks the “Sign In” button, a message is generated and the user is prompted to sign it using their connected wallet.
Signing Messages
The user signs the message with their wallet, and the signature is sent to the server.
You define the server logic location using the authConfig
prop on the
ThirdwebProvider.
You can see this inside the _app.tsx file:
Verifying Signatures
The signed message arrives at the server, and the server verifies the signature’s validity.
The application comes with a /pages/api/auth/[...thirdweb].ts
catch-all dynamic route
which handles /login
, /logout
, and /user
requests under the hood.
In this flow, the /login
route is triggered which verifies the signature and sets a thirdweb_auth_token
cookie for this user to remain
authenticated for future requests.
Accessing Restricted Data
Now the user is authenticated, you can use the useUser hook to access their authentication information from the client, as well as the useLogin and useLogout hooks to manage the user’s authentication state.
You can also restrict access to content based on the user’s authentication status or their wallet address on the server-side. The application showcases this in the secret.ts API route: