JWT decode and verify returns an empty object

Hi,

I’m working on an Apollo graphQL server, running in Azure Functions, and a React App authorization flow following these guides: Secure GraphQL, React, and Apollo Apps with Auth0, Apollo Docs | Authentication and Authorization and The Complete Guide to React User Authentication with Auth0.

I want to verify the access_token and retrieve user email in the graphQL Api but instead I’m getting an empty object.

Here is the API code:

const jwt = require('jsonwebtoken');
const jwksClient = require('jwks-rsa');
const client = jwksClient({
    jwksUri: `https://${process.env.AUTH0_DOMAIN}/.well-known/jwks.json`
});
function getKey(header, callback){
    client.getSigningKey(header.kid, function(err, key) {
        var signingKey = key.publicKey || key.rsaPublicKey;
        callback(null, signingKey);
    });
}
const options = {
    audience: `https://${process.env.AUTH0_DOMAIN}/api/v2/`,
    issuer: `https://${process.env.AUTH0_DOMAIN}/`,
    algorithms: ['RS256']
};
async function getUser (token) {
    const user = new Promise((resolve, reject) => {
        jwt.verify(token, getKey, options, (err, decoded) => {
            if(err) {
                return reject(err);
            }
            resolve(decoded.email)
        })
    })
    return user
}
const server = new ApolloServer({
    typeDefs,
    resolvers,
    debug: true,
    context: ({ request }) => ({
        user: getUser(request.headers.authorization)
    }),
})

Access Token was generated in the client using:

const render = (Component) => {
    ReactDOM.render(
        <Auth0Provider
            domain={domain}
            clientId={clientId}
            audience=`https://${domain}/api/v2/`
            scope= "openid email"
        >
            <Component/>
        </Auth0Provider>,
        document.getElementById("authCallback")
    );
};
const authCallback = () => {

    const { user, getAccessTokenSilently } = useAuth0();

    useEffect(
        () => {
            let accessToken
            const getToken = async () => {
                try {
                    accessToken = await getAccessTokenSilently({
                        scope: 'openid email'
                    });
                } catch (e) {
                    console.log(e.message)
                }
            }; 
            getToken()
        
        }, [getAccessTokenSilently, user?.sub]
    );

Context:

  • Client SDK: “auth0-react”: “1.8.0”
  • API dependencies:
    “apollo-server-azure-functions”: “3.3.0”
    “apollo-server”: “2.25.2”
    “graphql”: “15.5.1”
    “jsonwebtoken”: “8.5.1”
    “jwks-rsa”: “2.0.5”

I will really appreciate any help.

Looks like you have a couple things to fix here. First, getUser is an async function, so you’ll have to await it. As such, your context block will look like so:

    context: ({ request }) => ({
        user: await getUser(request.headers.authorization)
    }),

Also, I think the name of the request object is actually just req, so replace request with req in that bit of code and you should be good to go.