Zaubrik / djwt

Create and verify JSON Web Tokens (JWT) with Deno or the browser.
MIT License
228 stars 23 forks source link

Cannot verify token/secret which verifies successfully using Node #75

Closed mlanza closed 2 years ago

mlanza commented 2 years ago

While I am new to JWT I have run virtually the same code through Node's jsonwebtoken library and it works. I am targeting this library, however, to reduce my bundling dependencies.

Running decode against my JWT works fine. Running verify, however, results in a null exception:

error: Uncaught TypeError: Cannot read properties of undefined (reading 'name')
    if (keyAlgorithm.name === algAlgorithm.name) {
                     ^
    at verify (https://deno.land/x/djwt@v2.7/algorithm.ts:46:22)
    at Module.verify (https://deno.land/x/djwt@v2.7/mod.ts:151:7)
    at file:///xxx/xxx/xxx/xxxx/src/cf/jwt.js:15:28

Here's what I'm running:

//import jwt from "jsonwebtoken"; //I used Node's experimental-module syntax and it works fine.
import * as jwt from "https://deno.land/x/djwt@v2.7/mod.ts";

const token = "...";
const JWT_SECRET = "...";

const decoded = await jwt.decode(token); //success
console.log("decoded", decoded);  

const verified = await jwt.verify(token, JWT_SECRET); //fail!
console.log("verified", verified); 

I am certain my secret and token are fine having confirmed them in Node. The only difference is Node's methods are synchronous and don't require await.

My decoded payload follows, sensitive content elided:

[
  { alg: "HS256", typ: "JWT" },
  {
    aud: "authenticated",
    exp: 1664581993,
    sub: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    email: "someone@somewhere.com",
    phone: "",
    app_metadata: { provider: "email", providers: [ "email" ] },
    user_metadata: {},
    role: "authenticated",
    session_id: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
  },
  Uint8Array(32) [ ...
  ]
]
mlanza commented 2 years ago

For what it's worth, I just reduced my version to use:

import * as jwt from "https://deno.land/x/djwt@v2.1/mod.ts";

and added "HS256":

const verified = await jwt.verify(token, JWT_SECRET, "HS256");

And this works! But not in 2.7.

timonson commented 2 years ago

Hi @mlanza , you need a CryptoKey as key in version v2.7 because they are supposed to be more secure. Maybe the examples, which you can find here, will help you.

mlanza commented 2 years ago

Thank you. I will look into that, but to get up and running I am content with using the older version for now.