Search code examples
javascriptnode.jsgoogle-chrome-extensiongoogle-oauthgoogle-auth-library-nodejs

Error when generating a token in a js chrome extension when trying to verify it on a backend nodejs server


I am trying to generate a token in a chrome extension and then use it to verify requests to the backend server. I have been successful at generating a token in the front end but when I send it to the backend and verify it with the nodejs library google-auth-library but always get the error Error: Wrong number of segments in token: [TOKEN_HERE].

I have tried to find out how to fix it online and nothing that I have found works. The ID of my extension is the same as the ID in the console.

I created a chrome extension application in the developer console and added this to my manifest:

"oauth2": {
    "client_id": "THE ID",
    "scopes":["https://www.googleapis.com/auth/classroom.topics.readonly", "https://www.googleapis.com/auth/classroom.topics","https://www.googleapis.com/auth/classroom.courses.readonly", "https://www.googleapis.com/auth/classroom.rosters.readonly", "https://www.googleapis.com/auth/classroom.student-submissions.me.readonly"]
  },
...
"permissions": [
    "identity",
],

Once I ran the code

chrome.identity.getAuthToken({interactive: true}, function(token) {
    console.log(token);
});

It generates a token that I was able to validate in the extension with:

var x = new XMLHttpRequest();
x.open('GET', 'https://www.googleapis.com/oauth2/v1/userinfo?alt=json&access_token=' + token);

This also generated a new oAuth2 client in my console that is a web application: https://i.sstatic.net/pbp3J.png

On the backend nodejs server I tried using both of the generated IDs to verify the token. The extension application doesn't have a client secret but the webapp does. I have tried using the secret with the webserver id but this didn't work either.

This the code for the backend verification:

const { OAuth2Client } = require('google-auth-library');
const authClient = new OAuth2Client(CLIENT_ID);

async function verify(token) {
  const ticket = await authClient.verifyIdToken({
      idToken: token,
      audience: [CLIENT_ID]  // Specify the CLIENT_ID of the app that accesses the backend
      // Or, if multiple clients access the backend:
      //[CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3]
  });
    const payload = ticket.getPayload();
    return {
        domain: payload['hd'],
        userid: payload['sub']
    }
}

I want to verify the token with this code but it is unable to do so. Every time I use the token that is verifiable with the xhr request it just gives me the error Error: Wrong number of segments in token. I have no clue where to go from here as documentation is a bit scarce. All help is appreciated!

EDIT: I have also tried to validate the token with the Bearer prefix it didn't work.

EDIT 2: I have figured out the problem! ... just not the solution. Will update when I figure it out. Just so you know the reason why it doesn't work is that the way I tried getting the token gave me an access token and not an ID token. I am going to try and find out how to verify access tokens and more.


Solution

  • If you are looking to verify an access token (what is returned from chrome.identity) on a backend server then use this code:

    const { OAuth2Client } = require('google-auth-library');
    const authClient = new OAuth2Client(CLIENT_ID, CLIENT_SECRET);
    
    authClient.getTokenInfo(token)
    

    If authClient.getTokenInfo(token) errors out then the token is not valid.