I am looking for a solution on how to validate a token issued by Auth0 in a nodejs backend using jwt, but I keep

My React frontend uses Auth0 for user authentication. Once a user is logged in, I retrieve the token using getAccessTokenSilently() and send it to the backend like this:

const { user, isAuthenticated, getAccessTokenSilently } = useAuth0()

useEffect(() => {
    if (user) getTickets()
}, [user])

async function getTickets() {
    const token = await getAccessTokenSilently()
    const response = await fetch('http://localhost:4000/api/gettickets', {
        method: 'POST',
        headers: {
            Authorization: `Bearer ${token}`,
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({ user, bar }),
    })
    const data = await response.json()
}

After receiving the token in my backend, I attempt to verify it using jsonwebtoken with the following code:

import express from 'express'
import jwt from 'jsonwebtoken'
import dotenv from 'dotenv'
dotenv.config()

const routerGetTickets = express.Router()

routerGetTickets.post('/', async (req, res) => {
    const PUBKEY = process.env.PUBKEY
    const token = req.headers.authorization?.split(' ')[1]

    if (token && PUBKEY) {
        jwt.verify(token, PUBKEY, { algorithms: ['RS256'] }, (err, data) => {
            console.log('token :>> ', token)
            if (err) {
                res.sendStatus(403)
                console.log('err :>> ', err)
                return
            } else {
                console.log('everything ok')
            }
        })
    }
})
export default routerGetTickets

To use algorithm RS256, I extracted the public key using openssl with the signing certificate downloaded from my application in the Auth0 dashboard.

The error message I encounter is:

err :>>  JsonWebTokenError: secretOrPublicKey must be an asymmetric key when using RS256

This is my index.ts file:

import React from 'react'
import ReactDOM from 'react-dom/client'
import './sass/index.scss'
import App from './App'
import { BrowserRouter } from 'react-router-dom'
import { Auth0Provider } from '@auth0/auth0-react'

const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)

root.render(
<React.StrictMode>
    <BrowserRouter basename='/tombola'>
        <Auth0Provider
            domain='*******.uk.auth0.com'
            clientId='*****************************'
            authorizationParams={{
                redirect_uri: `${window.location.origin}/tombola/callback`,
                audience: 'https://******.uk.auth0.com/api/v2/',
                scope: 'read:current_user update:current_user_metadata'

            }}
        >
            <App />
        </Auth0Provider>
    </BrowserRouter>
</React.StrictMode>
)

Answer №1

Encountered the same issue with the verify jwt method while using Auth0, and it was traced back to a problem with the public key.

You may have obtained your PUBKEY variable from the Application settings section in Auth0's dashboard under advanced settings, as per the Auth0 documentation. However, this is actually the certificate, not the public key.

To retrieve the public key, you can utilize the "jwks-rsa" library, which fetches the public key using the certificate located on your Auth0 application domain. This process requires two key components:

1- The domain to construct the URL where Auth0 serves the keys.

2- The "kid" header of your JWT token, which identifies the correct key.

The code snippet looks like this:

async function HandleRequest(req, res) {
const cookie = req.headers.cookie;

const token = cookie.split(';')
.find(c => c.trim().startsWith("access_token="))
.split("=")[1]

const kid = decode(token, { complete: true }).header.kid;

const publicKey = (await JwksRsa({
    cache: true,
    rateLimit: true,
    jwksRequestsPerMinute: 5,
    jwksUri: `https://${process.env.DOMAIN}/.well-known/jwks.json`
}).getSigningKey(kid)).getPublicKey()

if (cookie && cookie.includes("access_token")) {
    verify(
        token,
        publicKey,
        {
            algorithms: ["RS256"],
        },
        (err, decoded) => {
            if (err) {
                res.write(JSON.stringify(err));
            } else {
                res.write(JSON.stringify(decoded));
            }
        }
    );
} else {
    res.write("No access token found")
}
res.end();
return
}

It is important to note that in this example, I am within an API route handling a request and extracting the JWT token from the headers. Your JWT token might be labeled differently. After decoding it, extracting the "kid" identifier, and passing it to jwks-rsa along with the constructed domain URL, the jwks-rsa library takes care of requesting the certificate from your Auth0 application and handling all the cryptographic work involved in retrieving the public key from the certificate.

You could potentially extract the certificate using the "crypto" node module, but working with .pem files proved to be more effective than dealing with strings. Nonetheless, it is valuable knowledge to possess.

I hope this explanation assists you, as navigating through Auth0 can be quite challenging during the learning process.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Component not being returned by function following form submission in React

After spending a few weeks diving into React, I decided to create a react app that presents a form. The goal is for the user to input information and generate a madlib sentence upon submission. However, I am facing an issue where the GenerateMadlib compone ...

The Express.js server is experiencing difficulty rendering CSS and JS files

Currently, I am in the process of following a tutorial on NODE.js and Express.js via YouTube. However, I have encountered an issue when it comes to rendering the CSS and JS files of a webpage using Express. Surprisingly, the index.html and logo.svg files a ...

Dealing with Numerous Checkboxes using Material UI and Formik

I'm working on a form that includes a checkbox group with 4 checkboxes. My goal is to pass these values to an API upon submitting the form using Formik. There are specific conditions based on which checkboxes are checked: If the 'Height' c ...

Utilizing Angular routing in HTML5 mode within a Node.js environment

While I've come across other solutions to this problem, they all seem to have drawbacks. One option leads to a redirect, which could be disastrous for my front-end application that relies on Mixpanel. A double-load of Mixpanel results in a Maximum Ca ...

What could be the reason for why get/post methods are causing Unauthorized (401) errors?

My project involves both a log-in and sign-up feature. For the sign-up part, I utilized Express-Validator, while for the log-in part, I integrated Passport.JS. However, when I added the passport JS declaration in app.js, it resulted in an Unauthorized erro ...

Issue with Mongoose pre-update hook: changes not being saved in database despite hook functioning

It seems like there is a simple issue causing the contact.fullName value not to update, even though contact.middleName updates correctly. The hook is triggering and the changes are showing up in the console logs, but not in the database. The fullName fiel ...

Customize Material-UI icons dynamically by changing their props in an array

I am looking to change props (color, size) for multiple icons in an array using Material-UI v4: const ICONS_ARRAY: React.ReactNode[] = [ <AlertCircleCheckOutline />, <AppleSafari />, <MotionPlay />, <AppleKeyboardCommand />, <Fil ...

The object function router(req, res, next) is encountering an error as it does not contain the required method for handling the request

I am trying to add a new row to my MySQL database, but I encountered an error message. Here is the scenario: I have set up Passport and hjs in my project. I am passing form data from app.js to a JavaScript file where I aim to insert the data. Object funct ...

Vercel deployed Next-App encountering issues: Request for a new refresh token triggers an unexpected 304 Not Modified response

For my latest project, I developed a Next.js frontend app and deployed it on Vercel, along with a Django backend app on Heroku. The authentication mechanism I used involves JWTs and a connection between the Next.js frontend and Django backend through a Nex ...

Encountering an issue when trying to dynamically import React Material UI Icons

Hey there, I'm currently working on dynamically loading icons from MUI using the following code snippet: import React from "react"; import * as MuiIcons from "@mui/icons-material"; console.log("MuiIcons: ", MuiIcons); co ...

Error message: "Supabase connection is returning an undefined value

I am encountering an issue with my Vercel deployed Remix project that utilizes Supabase on the backend, Postgresql, and Prisma as the ORM. Despite setting up connection pooling and a direct connection to Supabase, I keep receiving the following error whene ...

Having trouble with the Refresh or Direct Url not functioning properly after bundling with webpack in a React JS project

I encountered an error where the react js app with browser history was only functioning normally. However, after building with webpack, I faced issues with refreshing or pasting relative URLs. Switching to hash history resolved the problem. Despite trying ...

Effortlessly passing props between components using React TypeScript 16.8 with the help

In this scenario, the component is loaded as one of the routes. I have defined the type of companyName as a string within the AppProps type and then specified the type to the component using <AppProps>. Later on, I used {companyName} in the HTML rend ...

Label filledInput displayed outside of the input field

I'm currently working with <FilledInput/> using Material UI in conjunction with <InputLabel/>. However, I've encountered an issue where the label is not centered vertically and seems to move "out of bounds" when focused (appearing lik ...

Encountering a Module node browserify issue

I recently attempted to utilize the Dyson module node from https://github.com/webpro/dyson#installation. However, upon executing the 'dyson' command, I encountered the following error in my terminal. $ dyson Prueba/ module.js:491 throw err ...

Out of the blue synchronization issues arising from utilizing the nodejs events module

In my code, I am utilizing the Node Events module to execute a function asynchronously. var events = require('events'); var eventEmitter = new events.EventEmitter(); eventEmitter.on('myEvent', f2); function f1(x, y) { console.log( ...

Styling the Padding of MUI Select Component in ReactJS

Currently, I am facing an issue with the Material UI Select component where I am trying to decrease the padding within the element. The padding seems to be a property of one of the subclasses .MuiOutlinedInput-input, but my attempts to change the padding h ...

Performing multiple ajax calls simultaneously in JavaScript using the React framework

Within my React application, I am faced with the challenge of handling an array of parameters (such as IDs) that need to be passed as parameters in a queue of ajax calls. The issue arises when this array exceeds 1000 items, causing the browser page to beco ...

Sporadic error message: EADDRINUSE :::5000

There are times when rebooting my server resolves the issue, while at other times it doesn't. I keep encountering the error message Error: listen EADDRINUSE :::5000. In the package.json file of my client, I have set a proxy to "proxy": "http://localho ...

The Express application appears to be unresponsive, but the data has been successfully saved to the MongoDB database. An error with the

Currently, I am delving deeper into the MERN stack and working on a straightforward CRUD application utilizing it. One of the recent additions to the app includes validators implemented through express-validator for handling requests. However, an issue ari ...