how can get the property from result of jwt.verify() method that was already created

Viewed 1687

In my node.js project, I have used typescript.

I want to get userId from the result of jwt.verify() but I got an error.

How can I fix this problem? (If I don't use typescript, there is no problem.)

userService.ts file:

In Login method I have the following code:

import jwt from "jsonwebtoken"; 

// I have defined userId
token = jwt.sign({ userId: userId, email: email }, secretKey, { expiresIn: expiresIn });

check-auth.ts file:

Also in check-auth middleware I have:

 import jwt from "jsonwebtoken";


 const decodedToken = jwt.verify(token, process.env.SECRET_KEY);

 // Property 'userId' does not exist on type 'string | object'.
 // Property 'userId' does not exist on type 'string'.ts(2339)

 req.userData = { userId: decodedToken.userId }; // I need to access to the userId
2 Answers

The problem is jwt.verify doesn't know what might be inside encoded token string. In fact there may be anything signed with the right key. So you must hint TS about the expected type. As the most quick solution:

type MyToken = {
  userId: string
  email: string
  iat: number
  exp: number
}

const decodedToken = jwt.verify(token, process.env.SECRET_KEY) as MyToken;

req.userData = { userId: decodedToken.userId }; // ok

Though for production code I'd use something like assertion function to verify contents of the decoded token:

type MyToken = {
  userId: string
  email: string
  iat: number
  exp: number
}

const decodedToken: unknown = jwt.verify(token, process.env.SECRET_KEY);

function verifyDecodedToken(data: unknown): asserts data is MyToken {
  if (!(data instanceof Object)) 
    throw new Error('Decoded token error. Token must be an object');
  if (!('userId' in data)) 
    throw new Error('Decoded token error. Missing required field "userId"');

  // other necessary checks
}

verifyDecodedToken(decodedToken);

req.userData = { userId: decodedToken.userId }; // ok

playground link

Replace

import jwt from "jsonwebtoken";

with

import * as jwt from "jsonwebtoken";

// example,
import * as jwt from "jsonwebtoken"; 
let secretKey = "test";
let token = jwt.sign({ userId: "test", email: "test@test.com" },secretKey,{ expiresIn: 300000 });
const decodedToken = jwt.verify(token, secretKey);
let result = { userId: decodedToken.userId }; // I need to access to the userId
console.log(result);
Related