What could be the root cause behind the error encountered while trying to authenticate a JWT?

I've been working on integrating a Google OAuth login feature. Once the user successfully logs in with their Google account, a JWT token is sent to this endpoint on my Express server, where it is then decoded using jsonwebtoken:

app.post('/login/google', express.urlencoded(), async(request, response, next) => {
    try {
        console.log(`${request.method} ${request.url} was called.`);
        let token: string = request.body.credential;
        let decoded = jwt.verify(token, Globals.GoogleSecret, { algorithms: ['RS256'], ignoreExpiration: false });
        response.sendStatus(200);
    }
    catch (error) {
        next(error);
    }
});

The decoded token extracted from the request body appears valid (I even checked it on jwt.io).

The error being caught states:

code: 'ERR_OSSL_PEM_NO_START_LINE'
function: 'get_name'
library: 'PEM routines'
reason: 'no start line'
message: 'error:0909006C:PEM routines:get_name:no start line'

Can someone provide insight into what might be causing this issue and how to resolve it?

Some additional information for clarity:

  • Globals.GoogleSecret is a string set as the Client secret value found under my OAuth 2.0 Client ID Credential in the API Console.
  • I have an Angular web app accessible at http://localhost:4200/.
  • This app sends the Google OAuth credentials to the Express server using
    data-login_uri="http://localhost:1337/login/google"
    .
  • The development environment is Windows-based, coding done in VSCode.

Answer №1

After some troubleshooting, I managed to get everything working smoothly. Encountering this particular issue really made me rethink my approach. It turned out that the problem stemmed from using the incorrect key. When navigating to the Credentials section in the API Console, you'll notice a small icon located on the right side of your OAuth 2.0 Client ID credentials with a tooltip that reads, Download OAuth client. Upon clicking and examining the JSON file, you'll come across this specific line:

"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",

By visiting the provided URL, you'll be met with a JSON payload containing multiple certificates. Only one will work correctly for decoding and verifying the JWT, so it's essential to test each one until you find the right match. Additionally, I had to adjust the text format of the certificate for the verify function as shown below:

let certificate: string = `-----BEGIN CERTIFICATE-----
MIIDJjCCAg6gAwIBAgIId3xPl4cPKh0wDQYJKoZIhvcNAQEFBQAwNjE0MDIGA1UE
AwwrZmVkZXJhdGVkLXNpZ25vbi5zeXN0ZW0uZ3NlcnZpY2VhY2NvdW50LmNvbTAe
Fw0yMjA2MjQxNTIxNTlaFw0yMjA3MTEwMzM2NTlaMDYxNDAyBgNVBAMMK2ZlZGVy
YXRlZC1zaWdub24uc3lzdGVtLmdzZXJ2aWNlYWNjb3VudC5jb20wggEiMA0GCSqG
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDLFEiG1xHTWjedvqFec+PVTYVs2Do2gvYo
aQkYHlAtYxXuox3G8f+g6w/+yrvUSc1fOeZRzsW8r1F+hDHLUkYUzqArOQj7CpfA
VWGkLNapbWlxzOgnw5Ne2bWW1Y7rcoXKHY2knooU5Uiceo2g/z9BbAITX+p8RCvJ
6yG/mEE8aC7d7oO4P1LMnSFMYeuKdsRHx3GasZwGup7K+ox0PECKxho/E0Q4BOFI
igaTkm5D10dZC1hkp+jL293SRUWfIemyzemATDiufR5+v8aa8XlX8kasyQ5omynw
3+qm6da0f8Dteg+uMjDYDY1T9k56+3Tt/MpmPCzV3QceaccDs9azAgMBAAGjODA2
MAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMBYGA1UdJQEB/wQMMAoGCCsG
AQUFBwMCMA0GCSqGSIb3DQEBBQUAA4IBAQBUYM/QEuMEjqq/NHtd6w5tOL8FOkat
+2d3txRwIhDWaMOyDeM53Tufp1yhRpp3K46NnTkZRE6h4mGN7VPJWSED6s1FQGxA
2C6WkjnDshNxVzOh8+eZt3l8/gfzaR6lfMNH6NYoInl22GoS/46XRE3qY7RO9uVk
j8Uou1L6YdOPFA9buTjLHbJViGpz2vTt67C6ZMRC/exWINs8914buqXH2T99xJJM
T1FVInIpj+AROcjCnONerT/M0hrhTqGZy0WHsEXy7fZX/8EsJ79LXHkcR/tooO1s
ygZ79Xxy/2JDCH3QouXQJOs8iV697+3macsmzm9g/xBKXyllkEq3Q1xh
-----END CERTIFICATE-----`;

The critical step here is to replace all instances of the \n characters with actual newlines. Note that I used backtick template literals ` specifically for this purpose. Furthermore, make sure to eliminate any unnecessary whitespace within the literal, especially if you're copying and pasting the certificate into a code editor. Finally, after making these adjustments, I successfully utilized the following snippet to decode the JWT:

let decoded = jwt.verify(token, certificate, { algorithms: ['RS256'], ignoreExpiration: false });

While I'm unsure if this method is ideal due to my reservations about pinned certificates, it appears to be relatively effective. If you have insights or alternative approaches to share, please don't hesitate to provide feedback either in the comments below or by posting an answer.

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

Retrieve the Ionic storage item as a string

My issue is related to the code snippet below: this.storage.get('user') Upon execution, it returns the following object: t {__zone_symbol__state: null, __zone_symbol__value: Array(0)} I am uncertain about how to handle this object. Is there ...

What is the best way to alter the header in Django when a user is authenticated?

In my project, I have two headers: header.html and headersuccess.html. When a user is logged in, I need to change the header from header.html to headersuccess.html. How can I implement that? Here is an excerpt from my views.py file where I render loginsuc ...

Find the ID of the clicked table row using HTML and JavaScript

Currently, I am trying to implement this code snippet: <td align="center"> <div class="dropdown"> <button onclick="DropdownShow(this)" class="btn btn-default glyphicon glyphicon-picture"></button> <div id="@TableR ...

Ensuring Valid Submission: Utilizing Jquery for a Straightforward Form Submission with 'Alajax'

After searching for a straightforward JQuery plugin to streamline the process of submitting forms via Ajax, I stumbled upon Alajax. I found it quite useful as it seamlessly integrates into standard HTML forms and handles all the necessary tasks. However, I ...

How can you retrieve the property value from an object stored in a Set?

Consider this scenario: SomeItem represents the model for an object (which could be modeled as an interface in Typescript or as an imaginary item with the form of SomeItem in untyped land). Let's say we have a Set: mySet = new Set([{item: SomeItem, s ...

Exploring arrays within objects with Angular

REACT: this.countries = this.api.fetchAllCountries(); this.countries.forEach(item => { this.countryData.push(item); }); VUE: <div v-for="country in countryData" @click="displayCountryInfo(country ...

Steps for referencing a custom JavaScript file instead of the default one:

Currently, I am utilizing webpack and typescript in my single page application in combination with the oidc-client npm package. The structure of the oidc-client package that I am working with is as follows: oidc-client.d.ts oidc-client.js oidc-client.rs ...

Create a web application in NodeJS that mimics browser functionality by running JavaScript code from an HTML page

I'm a beginner in NodeJS and I am working on developing a web service that can send a response with the output of a JavaScript script from an HTML page sourced online. For instance: Imagine my webpage contains a JavaScript snippet that outputs "hell ...

Having trouble with NVM not working correctly in Ubuntu 21.04 Terminal?

Lately, I've been facing challenges with updating my Node.js version, and one method I tried was using node version manager. After downloading the install_nvm.sh file with the command curl -sL https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/insta ...

Unable to locate the value of the query string

I need help finding the query string value for the URL www.example.com/product?id=23 This is the code I am using: let myApp = angular.module('myApp', []); myApp.controller('test', ['$scope', '$location', '$ ...

Create a dynamic onClick event script and integrate it into Google Optimize

I need to incorporate a button element into my website using Google Optimize for an experiment. This button needs to trigger a specific script depending on the variation of the experiment. I have attempted two different methods: <button id="my-button" ...

Encountered an unhandled rejection error: TypeError: Unable to destructure the property 'protocol' of 'window.location' because it is undefined

I integrated the react-tradingview-widget into my nextjs project and it was working perfectly on version 10.2.3. However, after upgrading to version 12.1.4, I encountered an error when trying to reload the tradingview component. The error message was: unh ...

Requirements for using Angular JS and Node JS

With upcoming projects involving AngularJS and Node.js, I'm a bit apprehensive as I don't have much experience with JavaScript. Should I start by picking up a book on each technology, or is it essential to learn more about JavaScript first before ...

Control the button's activation status by accepting or unaccepting the two checkbox conditions

In my search through stackoverflow for help on enabling/disabling a button conditionally, I found some assistance but nothing quite matched what I needed. My situation involves two checkbox conditions rather than just one. The button should only be enable ...

Unable to Transmit Authorization Header in Cross-Domain Access Situation

My Node.js server has cross-origin communication enabled, allowing my Vue application to access its API from a different origin where static assets are served. This is achieved by setting the following code in Node.js: res.setHeader('Access-Control-Al ...

Django issue: A Tuple or struct_time argument is necessary

Currently, I am developing a code that deals with 2 variables - showdate and viewtype. Both of these variables are transferred via JavaScript using the POST method. viewtype = send an srt showdate = send a date from javascript Within this code snippet, ...

What causes Next.JS to automatically strip out CSS during the production build process?

Encountering unpredictability in CSS loading while deploying my Next.JS site. Everything appears fine locally, but once deployed, the CSS rules seem to vanish entirely. The element has the attached class, yet the corresponding styling rules are nowhere to ...

Displaying an HTML button above JavaScript code

Hello, I am currently working on a project that involves displaying the Earth and I am in need of assistance with positioning some buttons on the screen. Currently, I am facing an issue where the buttons appear either above or below the JavaScript code. I ...

Here are the steps for transferring data between two Node.js applications:

Running two Node.js apps on the same AWS EC2 instance serves unique purposes. The first app acts as an API gateway, handling credentials and request throttling, while the second app manages database information. Although they will eventually become separat ...

Verify the completeness of data types within an array in typescript

I am currently developing a comprehensive match function that I want to ensure is exhaustive during compile time. Although adding a default case would help with this, I am intrigued by some interesting dependent typing techniques I have come across. It wou ...