I’m getting “Invalid audience” when trying to verify the token on back-end. I don’t seem to find any documentation how and where should I define intended audience when I generate the token using web3auth.io in front-end. Any suggestions?
Hey @nika
Can you share more details like code snippets, SDK, and its version?
Meanwhile, this link might help. Also, see an example around it in our examples directory.
Hello @shahbaz , thanks for the quick reply. I’m attaching the front-end and back-end code
Front-end - sending token
and appPubKey
to back-end
const web3authProvider: any = await web3auth.connect();
const app_scoped_privkey: any = await web3authProvider.request({
method: "eth_private_key", // use "private_key" for other non-evm chains
});
const app_pub_key = getPublicCompressed(Buffer.from(app_scoped_privkey.padStart(64, "0"), "hex")).toString("hex");
const user = await web3auth.getUserInfo();
const res = await fetch("/api/v1/verify_user", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + user.idToken, // or token.idToken
},
body: JSON.stringify({ appPubKey: app_pub_key }),
});
Back-end - trying to verify the token, but getting “Invalid audience” error
authorization: str = request.headers.get("Authorization")
app_pub_key = (await request.json()).get("appPubKey")
id_token = authorization.split(' ')[1] if authorization else None
jwks_uri = "https://api.openlogin.com/jwks"
jwks_data = requests.get(jwks_uri).json()
jwks_data.get("keys")[0]["alg"] = "ES256"
data = jwks_data.get("keys")[0]
jwks = jwk.construct(data)
jwt_decoded = jwt.decode(id_token, jwks, algorithms=["ES256"])
Hey @nika
Please refer to our implementation of the same in frontend https://github.com/Web3Auth/examples/blob/main/web-no-modal-sdk/server-side-verification/ssv-via-social-nextjs-no-modal-example/pages/App.tsx#L92-L108 and backend https://github.com/Web3Auth/examples/blob/main/web-no-modal-sdk/server-side-verification/ssv-via-social-nextjs-no-modal-example/pages/api/login.ts#L20-L34
@shahbaz my code was practically same as you mentioned, I still changed front-end but still getting same error. When I decode jwt token generated in front-end I see “aud” property which I think might be causing the issue. Please check the screenshot attached, where and why is the “aud” value coming from?
Can you use jose to verify once?
// JWT verification using JWKS
import * as jose from "jose"
// passed from the frontend in the Authorization header
const idToken = req.headers.authorization?.split(' ')[1];
// passed from the frontend in the request body
const app_pub_key = req.body.appPubKey;
// Get the JWK set used to sign the JWT issued by Web3Auth
const jwks = jose.createRemoteJWKSet(new URL("https://api.openlogin.com/jwks"));
// Verify the JWT using Web3Auth's JWKS
const jwtDecoded = await jose.jwtVerify(idToken, jwks, { algorithms: ["ES256"] });
// Checking `app_pub_key` against the decoded JWT wallet's public_key
if ((jwtDecoded.payload as any).wallets[0].public_key === app_pub_key) {
// Verified
res.status(200).json({name: 'Verification Successful'})
} else {
res.status(400).json({name: 'Verification Failed'})
}
@shahbaz With javascript jose it works fine, I can verify the token with this code
const idToken = req.headers.authorization?.split(' ')[1] || '';
const app_pub_key = req.body.appPubKey;
const jwks = jose.createRemoteJWKSet(
new URL('https://api.openlogin.com/jwks'),
);
const jwtDecoded = await jose.jwtVerify(idToken, jwks, {
algorithms: ['ES256'],
});
console.log(jwtDecoded.payload)
The error message was misleading, I see the issue is somewhere in the python code which is supposed to do exactly same thing though. Do you have python example for back-end verification? This is the python code I’m trying to make work
authorization: str = request.headers.get("Authorization")
app_pub_key = (await request.json()).get("appPubKey")
id_token = authorization.split(' ')[1] if authorization else None
jwks_uri = "https://api.openlogin.com/jwks"
jwks_data = requests.get(jwks_uri).json()
jwks_data.get("keys")[0]["alg"] = "ES256"
data = jwks_data.get("keys")[0]
jwks = jwk.construct(data)
jwt_decoded = jwt.decode(id_token, jwks, algorithms=["ES256"])
Thanks for confirming that it works in the Node environment.
Can you try with the below code?
jwks_uri = "https://api.openlogin.com/jwks"
jwks = requests.get(jwks_uri).json()
jwt_decoded = jwt.decode(id_token, jwks, algorithms=["ES256"])
btw which package are you using? python-jose
?
@shahbaz yes, I’m using python-jose
. Getting same error “invalid audience” with your code:
authorization: str = request.headers.get("Authorization")
app_pub_key = (await request.json()).get("appPubKey")
id_token = authorization.split(' ')[1] if authorization else None
jwks_uri = "https://api.openlogin.com/jwks"
jwks = requests.get(jwks_uri).json()
jwt_decoded = jwt.decode(id_token, jwks.get("keys")[0], algorithms=["ES256"])
@shahbaz disabling verify audience did the trick. Thank you so much for helping out. Here is the final code that worked:
Front-end javascript:
const web3authProvider: any = await web3auth.connect();
const { idToken } = await web3auth.authenticateUser();
const privKey: any = await web3auth.provider?.request({
method: "eth_private_key",
});
const pubkey = getPublicCompressed(Buffer.from(privKey, "hex")).toString("hex");
const res = await fetch("/api/v1/verify_user", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${idToken}`,
},
body: JSON.stringify({ appPubKey: pubkey }),
});
Back-end python/python-jose:
authorization: str = request.headers.get("Authorization")
app_pub_key = (await request.json()).get("appPubKey")
id_token = authorization.split(' ')[1] if authorization else None
jwks_uri = "https://api.openlogin.com/jwks"
jwks = requests.get(jwks_uri).json()
jwt_decoded = jwt.decode(id_token, jwks.get("keys")[0], algorithms=["ES256"], options={'verify_aud': False})
This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.