使用 Deno 进行 JWT 身份验证

JWT authentication with Deno

如何在 Deno 中创建和验证 JSON Web 令牌?

我是 Deno 运行时的新手,所以如果有一个示例可以帮助您在 Deno 中开始使用 JWT。

这是一个简短的演示,展示了如何创建带有 HS256 签名的 JWT 以及如何验证它和提取有效载荷。

jwtdemo.ts(基于Version 2.4 of djwt):

import { create, verify , getNumericDate, Payload, Header} from "https://deno.land/x/djwt@v2.4/mod.ts";

const encoder = new TextEncoder()
var keyBuf = encoder.encode("mySuperSecret");

var key = await crypto.subtle.importKey(
  "raw",
  keyBuf,
  {name: "HMAC", hash: "SHA-256"},
  true,
  ["sign", "verify"],
)

const payload: Payload = {
  iss: "deno-demo",
  exp: getNumericDate(300), // expires in 5 min.
};

const algorithm = "HS256"

const header: Header = {
  alg: algorithm,
  typ: "JWT",
  foo: "bar"  // custom header
};

const jwt = await create(header, payload, key)

console.log(jwt);

// create a different key to test the verifcation
/*keyBuf = encoder.encode("TheWrongSecret");
key = await crypto.subtle.importKey(
  "raw",
  keyBuf,
  {name: "HMAC", hash: "SHA-256"},
  true,
  ["sign", "verify"],
)
*/

try {
  const payload = await verify(jwt, key); 
    console.log("JWT is valid");
    console.log(payload);
}
catch(_e){
  const e:Error= _e;
  console.log(e.message);
}

当前版本的 djwt 现在使用自 Deno 1.11. The functions create and verify need the key-parameter to be provided as an CryptoKey 对象以来可用的 Web Crypto API,因此即使对于 HS256,您也不能再传递一个简单的字符串,但需要创建一个适当的如上面代码第一行所示的关键对象。

辅助方法 getNumericDate(exp) 自动设置正确的 Unix 时间戳并将作为参数给定的秒数添加到当前时间或直接使用给定的日期参数。

你可以直接运行上面的demo,所有导入的模块都会自动下载:

deno run jwtdemo.ts

结果是:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImZvbyI6ImJhciJ9.eyJpc3MiOiJkZW5vLWRlbW8iLCJleHAiOjE2MzMzNzUyODl9.FBYgDrpG9RXJSfgme-430UyFLvdNTNliYTKGiWajksQ
JWT is valid
{ iss: "deno-demo", exp: 1633375289 }

或者,在签名错误的情况下(取消注释带有错误密码的代码块以测试它):

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImZvbyI6ImJhciJ9.eyJpc3MiOiJkZW5vLWRlbW8iLCJleHAiOjE2MzMzNzU0MDd9.F3szgyrTJSQG3m1a82OJkKqKIDD32Q21ZchAVAj74bk
The jwt's signature does not match the verification signature.

在 node.js 中创建 JWT 的一个显着区别是,我们在这里有预定义的接口 HeaderPayload 而不是简单的 JSON,并且会检查值。

当我设置

const algorithm = "XS256"   // instead of "HS256"

算法检查会失败,程序不会启动:

Check file:///C:/Users/jps/source/deno/jwtdemoV19.ts
error: TS2322 [ERROR]: Type '"XS256"' is not assignable to type 'Algorithm'.
  alg: algorithm,
  ~~~
    at file:///C:/Users/jps/source/deno/jwtdemoV19.ts:8:3

    The expected type comes from property 'alg' which is declared here on type 'Header'
      alg: Algorithm;
      ~~~
        at https://deno.land/x/djwt@v1.9/mod.ts:36:3

TS2345 [ERROR]: Argument of type '"XS256"' is not assignable to parameter of type 'AlgorithmInput'.
        const payload = await verify(jwt,  key, algorithm)
                                                ~~~~~~~~~
    at file:///C:/Users/jps/source/deno/jwtdemoV19.ts:26:42

Found 2 errors.

示例代码使用djwt 2.4版本,目前支持HSxxxRSxxxPSxxxESxxx(xxx为256之一, 384、512)签名算法。未来将添加更多算法,具体取决于 deno 加密模块中支持的可用性。

阅读 了解如何验证 RS256 签名令牌。

注意:此答案已被重写以涵盖 2.4 版中 djwt api 的重大更改。 old version of this post 基于 djwt v1.9