This repository has been archived by the owner on Jan 5, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 146
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* docs: add custom auth docs * chore: update slugs * chore: remove dup import * chore: fix user formatting * chore: update quickstart section * fix: remove duplicate import on auto save * chore: update wording * chore: update custom auth config, fix typos, and update title * chore: fix custom auth docs from feedback * fix: remove dup import * chore: update diagrams * chore: add clarification on quickstart link * chore: minor tweaks
- Loading branch information
1 parent
97ceb3f
commit 67563ea
Showing
6 changed files
with
365 additions
and
98 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,135 +3,170 @@ slug: /embedded-wallet/custom-auth-server | |
title: Custom Auth Server | ||
--- | ||
|
||
import TabItem from "@theme/TabItem"; | ||
import Tabs from "@theme/Tabs"; | ||
|
||
# Create a custom auth server | ||
|
||
Learn how to integrate your auth backend with our embedded wallets solution so you can onboard your users into web3 seamlessly. | ||
Learn how to integrate your auth backend with our embedded wallets solution so you can onboard your users into web3 seamlessly. | ||
|
||
This guide will show you how to create your own Auth Server. By doing so, you can have full control over user authentication and data security. This allows you to ensure that your application meets specific compliance requirements while also providing a customized sign-in experience. | ||
This guide will show you how to create your own Auth Server that is compatible with the `auth_endpoint` strategy. By doing so, you can have full control over user authentication and data security. This allows you to ensure that your application meets specific compliance requirements while also providing a customized sign-in experience. | ||
|
||
:::caution | ||
This guide is simplified for demonstration purposes and is not ready for production use. When modifying it for production, secure your endpoints and avoid hard-coding secrets or sensitive information. We recommend using environment variables and secret managers. | ||
::: | ||
|
||
### Setup | ||
## 5 minute quickstart | ||
|
||
1. Create a new directory for your project and navigate to it in your CLI | ||
1. Navigate to Wallets > [Embedded Wallets](https://thirdweb.com/dashboard/wallets/embedded) in the thirdweb dashboard. | ||
2. Create a thirdweb API key if you don't have one or select an existing key to use for this project. [Learn more about API keys.](https://portal.thirdweb.com/api-keys) | ||
|
||
```bash | ||
mkdir jwt-auth-server | ||
cd jwt-auth-server | ||
``` | ||
![Embedded wallet dashboard with create key displayed](../assets/ew-create-key.png) | ||
|
||
2. Initialize a new Node.js application | ||
3. Allowlist domain or bundle ids in Access Restrictions. | ||
4. Navigate to the Configuration view and enable **Custom Auth Endpoint** | ||
|
||
```bash | ||
npm init -y | ||
![Configuration view for embedded wallet](../assets/ew-custom-auth-config.png) | ||
|
||
yarn init -y | ||
``` | ||
5. Set the Auth Endpoint URL to `https://embedded-wallet.thirdweb.com/api/2023-11-30/embedded-wallet/auth/test-custom-auth-endpoint` for testing purposes. You will replace this later with your own auth server endpoint to verify the `payload`. | ||
6. Save the configuration. | ||
7. Copy the client ID. | ||
8. In your preferred thirdweb client SDK, pass the payload you retrieved from logging in to the server. | ||
|
||
3. Install the necessary packages | ||
You can now auth into the wallet and use it to sign transactions like so (see [use your own auth for more](/embedded-wallet/custom-auth)): | ||
|
||
```bash | ||
npm install express jsonwebtoken | ||
``` | ||
<Tabs> | ||
<TabItem value="react" label="React & React Native"> | ||
|
||
### **Generate RSA Key Pair:** | ||
In React and React Native, the `useEmbeddedWallet()` hook handles authentication and connection states. | ||
|
||
1. To generate a private and a public key run | ||
```typescript | ||
import { useEmbeddedWallet } from "@thirdweb-dev/react"; // or /react-native | ||
|
||
```bash | ||
ssh-keygen -t rsa -b 2048 -m PEM -f keys/rsa.key | ||
``` | ||
const embeddedWallet = useEmbeddedWallet(); | ||
|
||
2. To create the output file run | ||
const handlePostLogin = async () => { | ||
await embeddedWallet.connect({ | ||
strategy: "auth_endpoint", | ||
// in production this would be your public identifier for the user | ||
payload: JSON.stringify({ userId:"ANY_RANDOM_ID_HERE" }), | ||
encryptionKey: "ANY_RANDOM_STRING_HERE" | ||
}); | ||
}; | ||
``` | ||
|
||
```bash | ||
openssl rsa -in keys/rsa.key -pubout -outform PEM -out keys/rsa.key.pub | ||
``` | ||
</TabItem> | ||
<TabItem value="typescript" label="Other Typescript Frameworks"> | ||
|
||
### **Convert Public Key to JSON Web Key Set (JWKS):** | ||
In other frameworks, use your own instance of the wallet to authenticate and connect. | ||
|
||
1. Display the public key: | ||
```typescript | ||
import { EmbeddedWallet } from "@thirdweb-dev/wallets"; | ||
import { Goerli } from "@thirdweb-dev/chains"; | ||
|
||
```bash | ||
cat keys/rsa.key.pub | ||
``` | ||
const embeddedWallet = new EmbeddedWallet({ | ||
chain: Goerli, // chain to connect to | ||
clientId: "YOUR_CLIENT_ID", // Your thirdweb client ID | ||
}); | ||
|
||
const authResult = await embeddedWallet.authenticate({ | ||
strategy: "auth_endpoint", | ||
payload: JSON.stringify({ userId:"ANY_RANDOM_ID_HERE" }), | ||
encryptionKey: "ANY_RANDOM_STRING_HERE"= | ||
}); | ||
|
||
const walletAddress = await embeddedWallet.connect({ authResult }); | ||
``` | ||
|
||
2. Copy the displayed public key. | ||
3. Convert your public key to a JWK using an online JWK Creator tool. We recommend using [JWK Creator by Russel Davies](https://github.com/russelldavies/jwk-creator). | ||
</TabItem> | ||
</Tabs> | ||
|
||
1. Paste the public key, set Key ID as `0` (arbitrary string, must match when signing JWT), and then note down the generated JWK. | ||
A persistent, cross-platform wallet is now created for your user! | ||
|
||
![JWK Creator tool by Russel Davies showing key id of 0](../assets/jwk-creator-tool.png) | ||
Of course, you would use your own auth server instead of the one we provided. The rest of this guide will show you how to create your own auth server. | ||
|
||
4. Create a `jwks.json` in the project root and place the generated JWK in a `keys` array. | ||
### Setup | ||
|
||
The following steps will show you how to create a simple auth server that can be used with the embedded wallet. | ||
|
||
At a high level, the auth server will: | ||
|
||
1. Handle login for the user into your application. | ||
2. Have a way to get a public identifier for the user. | ||
3. Have an endpoint to verify the public identifier and return some basic information about the user | ||
|
||
Steps 1 and 2 are up to you to implement. You can use any auth strategy you want. | ||
|
||
The endpoint in step 3 is what your register as your auth endpoint on the thirdweb dashboard. | ||
|
||
Here's a high level diagram: | ||
![custom auth flow diagram](../assets/ew-custom-auth-flow.png) | ||
|
||
1. Create a new directory for your project and navigate to it in your CLI | ||
|
||
```bash | ||
mkdir custom-auth-server | ||
cd custom-auth-server | ||
``` | ||
|
||
2. Initialize a new Node.js application | ||
|
||
```bash | ||
{ | ||
"keys": [ | ||
{ | ||
... JWK ... | ||
} | ||
] | ||
} | ||
npm init -y | ||
|
||
yarn init -y | ||
``` | ||
|
||
### **Create the Server:** | ||
|
||
1. In the `jw-auth-server` directory, create a file at the root named `server.js` and paste the following: | ||
1. In the `custom-auth-server` directory, create a file at the root named `server.js` and paste the following: | ||
|
||
```jsx | ||
const express = require("express"); | ||
const fs = require("fs"); | ||
const jwt = require("jsonwebtoken"); | ||
|
||
const app = express(); | ||
const PORT = process.env.PORT || 3000; | ||
|
||
const PRIVATE_KEY = fs.readFileSync("./keys/rsa.key", "utf8"); | ||
const jwks = require("./jwks.json"); | ||
|
||
const users = [ | ||
{ id: 1, email: "[email protected]", password: "password123" }, | ||
]; | ||
|
||
app.use(express.json()); | ||
|
||
// This is what your app calls to login a user and get a public identifier for the user (otherwise known as the payload) | ||
app.post("/login", (req, res) => { | ||
const { email, password } = req.body; | ||
const user = users.find( | ||
(u) => u.email === email && u.password === password, | ||
); | ||
if (!user) return res.status(401).send({ message: "Invalid credentials" }); | ||
|
||
const payload = { | ||
iss: "http://your-domain.com", | ||
sub: user.id.toString(), | ||
aud: "EpicGame", | ||
email: user.email, | ||
exp: Math.floor(Date.now() / 1000) + 3600, | ||
}; | ||
|
||
const token = jwt.sign(payload, PRIVATE_KEY, { | ||
algorithm: "RS256", | ||
keyid: "0", | ||
}); | ||
|
||
res.send({ token }); | ||
res.send({ payload: user.id }); | ||
}); | ||
// This is a sample endpoint that yuou would register on the thirdweb dashboard for us to verify the payload | ||
app.get("/thirdweb-will-call-this", (req, res) => { | ||
const { payload } = req.body; | ||
if (!payload) return res.status(401).send({ message: "Invalid credentials" }); | ||
|
||
app.get("/.well-known/jwks.json", (req, res) => { | ||
res.json(jwks); | ||
// you would write your own logic here to verify the payload here | ||
const user = users.find((u) => u.id === payload); | ||
if (!user) return res.status(401).send({ message: "Invalid credentials" }); | ||
|
||
// once the user is successfully verified, you can return the following field | ||
return res.send({ | ||
userId: user.id, | ||
// the last two fields here are optional | ||
email: user.email, | ||
exp: Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 30, | ||
}); | ||
}); | ||
|
||
app.listen(PORT, () => { | ||
console.log(`Server started on port ${PORT}`); | ||
}); | ||
``` | ||
|
||
2. Replace `http://your-domain.com` with the actual domain for the application. | ||
|
||
### **Test Locally** | ||
|
||
1. Start the server: | ||
|
@@ -146,36 +181,10 @@ This guide is simplified for demonstration purposes and is not ready for product | |
curl -X POST http://localhost:3000/login -H "Content-Type: application/json" -d '{"email": "[email protected]", "password": "password123"}' | ||
``` | ||
|
||
3. Test JWKS: | ||
|
||
```bash | ||
curl http://localhost:3000/.well-known/jwks.json | ||
``` | ||
|
||
### **Deploy** | ||
|
||
To deploy the server, you can use use services such as [Zeet](https://zeet.co/) or [Docker](https://www.docker.com/). | ||
|
||
Once deployed, replace `http://localhost:3000` in the JWT payload with your actual domain | ||
|
||
### **Integrate Embedded Wallets** | ||
|
||
1. Navigate to Wallets > [Embedded Wallets](https://thirdweb.com/dashboard/wallets/embedded) in the thirdweb dashboard. | ||
2. Create a thirdweb API key if you don’t have one or select an existing key to use for this project. [Learn more about API keys.](https://portal.thirdweb.com/api-keys) | ||
|
||
![Embedded wallet dashboard with create key displayed](../assets/ew-create-key.png) | ||
|
||
3. Allowlist domain or bundle ids in Access Restrictions. | ||
4. Navigate to the Configuration view and enable **Custom JSON Web Token** | ||
|
||
![Configuration view for embedded wallet](../assets/ew-configuration.png) | ||
|
||
5. Set the JWKS URI to `your-domain/.well-known/jwks.json` | ||
6. Set the AUD to `EpicGame` or the value you set as the aud in the `server.js` file. | ||
|
||
![Options for EW Configuration](../assets/ew-configuration-opt.png) | ||
|
||
7. Copy the client ID. | ||
8. In your preferred thirdweb client SDK, pass the JWT you retrieved from logging in to the server. | ||
|
||
A persistent, cross-platform wallet is now created for your user. | ||
Refer top the [quickstart above](#5-minute-quickstart) to integrate the embedded wallet into your application. |
Oops, something went wrong.
67563ea
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
docs – ./
docs.thirdweb.com
docs-chi-eight.vercel.app
docs.thirdweb-preview.com
portal.thirdweb.com
docs-git-main.thirdweb-preview.com