Skip to content

Commit b362126

Browse files
committed
Update id-token.mdx
1 parent 4bc7fb7 commit b362126

File tree

1 file changed

+181
-25
lines changed

1 file changed

+181
-25
lines changed

docs/authentication/id-token.mdx

Lines changed: 181 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -143,41 +143,197 @@ with.
143143

144144
### Using JWKS Endpoint
145145

146-
JWKS Endpoint: `https://api-auth.web3auth.io/.well-known/jwks.json`
146+
<Tabs>
147+
<TabItem value="Social Login">
147148

148-
```js title="Example (Node.js with jose)"
149-
import * as jose from "jose";
149+
JWKS Endpoint: `https://api-auth.web3auth.io/jwks`
150150

151-
const idToken = req.headers.authorization?.split(" ")[1];
152-
const app_pub_key = req.body.appPubKey;
151+
```ts title="login/route.ts"
152+
import * as jose from "jose";
153+
import { NextRequest, NextResponse } from "next/server";
154+
155+
export async function POST(req: NextRequest) {
156+
try {
157+
//focus-start
158+
// Extract JWT token from Authorization header
159+
const authHeader = req.headers.get("authorization");
160+
const idToken = authHeader?.split(" ")[1];
161+
// Get public key from request body
162+
const { appPubKey } = await req.json();
163+
//focus-end
164+
165+
if (!idToken) {
166+
return NextResponse.json({ error: "No token provided" }, { status: 401 });
167+
}
153168

154-
const jwks = jose.createRemoteJWKSet(new URL("https://api-auth.web3auth.io/.well-known/jwks.json"));
155-
const jwtDecoded = await jose.jwtVerify(idToken, jwks, { algorithms: ["ES256"] });
169+
if (!appPubKey) {
170+
return NextResponse.json({ error: "No appPubKey provided" }, { status: 400 });
171+
}
156172

157-
// Verify wallet key match
158-
if (
159-
jwtDecoded.payload.wallets.find((w) => w.type === "web3auth_app_key").public_key.toLowerCase() ===
160-
app_pub_key.toLowerCase()
161-
) {
162-
res.status(200).json({ name: "Verification Successful" });
163-
} else {
164-
res.status(400).json({ name: "Verification Failed" });
173+
//focus-start
174+
// Verify JWT using Web3Auth JWKS
175+
// highlight-next-line
176+
const jwks = jose.createRemoteJWKSet(new URL("https://api-auth.web3auth.io/jwks"));
177+
const { payload } = await jose.jwtVerify(idToken, jwks, { algorithms: ["ES256"] });
178+
179+
// Find matching wallet in JWT
180+
const wallets = (payload as any).wallets || [];
181+
const normalizedAppKey = appPubKey.toLowerCase().replace(/^0x/, "");
182+
183+
const isValid = wallets.some((wallet: any) => {
184+
if (wallet.type !== "web3auth_app_key") return false;
185+
186+
const walletKey = wallet.public_key.toLowerCase();
187+
188+
// Direct key comparison for ed25519 keys
189+
if (walletKey === normalizedAppKey) return true;
190+
191+
// Handle compressed secp256k1 keys
192+
if (
193+
wallet.curve === "secp256k1" &&
194+
walletKey.length === 66 &&
195+
normalizedAppKey.length === 128
196+
) {
197+
const compressedWithoutPrefix = walletKey.substring(2);
198+
return normalizedAppKey.startsWith(compressedWithoutPrefix);
199+
}
200+
201+
return false;
202+
//focus-end
203+
});
204+
205+
if (isValid) {
206+
return NextResponse.json({ name: "Verification Successful" }, { status: 200 });
207+
} else {
208+
return NextResponse.json({ name: "Verification Failed" }, { status: 400 });
209+
}
210+
} catch (error) {
211+
console.error("Social login verification error:", error);
212+
return NextResponse.json({ error: "Verification error" }, { status: 500 });
213+
}
165214
}
166215
```
167216

168-
#### For External Wallets:
217+
</TabItem>
218+
<TabItem value="External Wallets">
169219

170-
```js
171-
if (
172-
jwtDecoded.payload.wallets.find((w) => w.type === "ethereum").address.toLowerCase() ===
173-
publicAddress.toLowerCase()
174-
) {
175-
res.status(200).json({ name: "Verification Successful" });
176-
} else {
177-
res.status(400).json({ name: "Verification Failed" });
220+
JWKS Endpoint: `https://authjs.web3auth.io/jwks`
221+
222+
```ts title="login-external/route.ts"
223+
import * as jose from "jose";
224+
import { NextRequest, NextResponse } from "next/server";
225+
226+
export async function POST(req: NextRequest) {
227+
try {
228+
//focus-start
229+
// Extract JWT token from Authorization header
230+
const authHeader = req.headers.get("authorization");
231+
const idToken = authHeader?.split(" ")[1];
232+
// Get address from request body
233+
const { address } = await req.json();
234+
//focus-end
235+
236+
if (!idToken) {
237+
return NextResponse.json({ error: "No token provided" }, { status: 401 });
238+
}
239+
240+
if (!address) {
241+
return NextResponse.json({ error: "No address provided" }, { status: 400 });
242+
}
243+
244+
//focus-start
245+
// Verify JWT using AuthJS JWKS
246+
// highlight-next-line
247+
const jwks = jose.createRemoteJWKSet(new URL("https://authjs.web3auth.io/jwks"));
248+
const { payload } = await jose.jwtVerify(idToken, jwks, { algorithms: ["ES256"] });
249+
250+
// Find matching wallet in JWT
251+
const wallets = (payload as any).wallets || [];
252+
const addressToCheck = Array.isArray(address) ? address[0] : address;
253+
const normalizedAddress = addressToCheck.toLowerCase();
254+
255+
const isValid = wallets.some((wallet: any) => {
256+
return (
257+
wallet.type === "ethereum" &&
258+
wallet.address &&
259+
wallet.address.toLowerCase() === normalizedAddress
260+
);
261+
});
262+
//focus-end
263+
264+
if (isValid) {
265+
return NextResponse.json({ name: "Verification Successful" }, { status: 200 });
266+
} else {
267+
return NextResponse.json({ name: "Verification Failed" }, { status: 400 });
268+
}
269+
} catch (error) {
270+
console.error("External wallet verification error:", error);
271+
return NextResponse.json({ error: "Verification error" }, { status: 500 });
272+
}
178273
}
179274
```
180275

276+
</TabItem>
277+
<TabItem value="Frontend Call">
278+
279+
```ts title="App.tsx"
280+
const {
281+
token,
282+
getIdentityToken,
283+
loading: idTokenLoading,
284+
error: idTokenError,
285+
} = useIdentityToken();
286+
287+
const validateIdToken = async () => {
288+
//focus-next-line
289+
const idToken = await getIdentityToken();
290+
291+
let res;
292+
if (connectorName === "auth") {
293+
//focus-start
294+
// Social login: send public key
295+
const pubKey = await web3Auth?.provider?.request({ method: "public_key" });
296+
console.log("pubKey:", pubKey);
297+
res = await fetch("/api/login", {
298+
method: "POST",
299+
headers: {
300+
"Content-Type": "application/json",
301+
Authorization: `Bearer ${idToken}`,
302+
},
303+
body: JSON.stringify({ appPubKey: pubKey }),
304+
});
305+
//focus-end
306+
} else {
307+
//focus-start
308+
// External wallet: send address
309+
const address = await web3Auth?.provider?.request({ method: "eth_accounts" });
310+
res = await fetch("/api/login-external", {
311+
method: "POST",
312+
headers: {
313+
"Content-Type": "application/json",
314+
Authorization: `Bearer ${idToken}`,
315+
},
316+
body: JSON.stringify({ address }),
317+
});
318+
//focus-end
319+
}
320+
321+
// Handle response
322+
if (res.status === 200) {
323+
toast.success("JWT Verification Successful");
324+
uiConsole(`Logged in Successfully!`, userInfo);
325+
} else {
326+
toast.error("JWT Verification Failed");
327+
await disconnect();
328+
}
329+
330+
return res.status;
331+
};
332+
```
333+
334+
</TabItem>
335+
</Tabs>
336+
181337
### Using Verification Key
182338

183339
To manually verify the token, use your **Verification Key** available on the **Project Settings**
@@ -219,7 +375,7 @@ npm install jsonwebtoken
219375
```
220376

221377
```js title="Example (JWT Verification using jsonwebtoken)"
222-
const verificationKey = "insert-your-privy-verification-key".replace(/\\n/g, "\n");
378+
const verificationKey = "insert-your-web3auth-verification-key".replace(/\\n/g, "\n");
223379

224380
const idToken = "insert-the-users-id-token";
225381

0 commit comments

Comments
 (0)