javascriptjwtcryptographysubtlecrypto

Verifying A JWT With The Crypto Web API


I am trying to verify a JSON Web Token using the Web Crypto API. This is my code so far:

async function verify(user: string) {
  const secret = await crypto.subtle.importKey(
    "raw",
    new TextEncoder().encode(process.env.SECRET!),
    {
      name: "HMAC",
      hash: { name: "SHA-256" },
    },
    false,
    ["verify"]
  );

  return crypto.subtle.verify(
    "HMAC",
    secret,
    Buffer.from(user.split(".")[2], "base64url"),
    new TextEncoder().encode(user.split(".").splice(0, 2).join())
  );
}

The parameter user contains the JWT. The variable process.env.SECRET contains the secret/key that was used to sign the token. It is of type string.

However, this function seems to always return false, even when passed a valid token. Can somebody help me figure out what I am doing wrong? Also, I would prefer not to use any external libraries for this.


Solution

  • I am just repeating what @Topaco commented on the original question, because that solved my issue and this way I can accept an answer and thereby close this.

    What I forgot what the argument for the join() method. For anybody else who wants to use the code I'll post the working version below.

    async function verify(user: string) {
      const secret = await crypto.subtle.importKey(
        "raw",
        new TextEncoder().encode(process.env.SECRET!),
        {
          name: "HMAC",
          hash: { name: "SHA-256" },
        },
        false,
        ["verify"]
      );
    
      return crypto.subtle.verify(
        "HMAC",
        secret,
        Buffer.from(user.split(".")[2], "base64url"),
        new TextEncoder().encode(user.split(".").splice(0, 2).join("."))
      );
    }