@@ -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
183339To 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
224380const idToken = " insert-the-users-id-token" ;
225381
0 commit comments