是否可以在不使用框架的情况下在 Node.js 中创建 JWT 身份验证或类似的东西?

Is it possible to create a JWT authentication or something similar in Node.js without using frameworks?

我正在创建一个网站,我知道最好的身份验证是通过 JWT,但我不喜欢框架,因为我喜欢深入研究代码并理解我文件中的所有代码.因此,我想问是否有人在纯粹的 Node.js 中完成了它或类似的事情,是否可以给我解释如何做到这一点。

谢谢

是的,当然可以,只要考虑框架是如何制作的。没有魔法,只有知识和大量 javascript 代码。

您可以在 Github 上找到大多数框架的源代码并在那里进行研究。

第一步,您应该熟悉 JWT 的基础知识,例如借助这个 introduction and by reading RFC7519.

您会发现,JWT 基本上由 base64url 编码 JSON objects 和 base64url 编码签名组成。

最简单的签名算法是HS256(HMAC-SHA256)。

jwt.io debugger window 中,您会在右栏中看到用于创建 JWT 签名的伪代码:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret
)

所以基本上你需要学习:

  • 什么信息进入 JWT header 和负载(即 claims
  • 如何base64url编码字符串或字节数组
  • 如何创建 SHA256 hash
  • 如何使用散列算法创建HMAC.

至此,您已经有了一个基本的 JWT 框架,可以让您创建签名令牌并验证签名。

在下一步中,您可以添加“功能”,例如

  • 有效期验证
  • 发行者、观众的验证
  • 高级签名算法。

您可以使用 jwt.io debugger 检查您的令牌是否可以被解码和验证。

根据您的需要,您可以使用如下内容:

export const setJwtToken = (headers, payload) => {

const base64Encode = str => {
    const utf8str = decodeURI(encodeURI(str))
    const b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
    const len = str.length
    let dst = ""
    let i

    for (i = 0; i <= len - 3; i += 3) {
        dst += b64.charAt(utf8str.charCodeAt(i) >>> 2)
        dst += b64.charAt(((utf8str.charCodeAt(i) & 3) << 4) | (utf8str.charCodeAt(i + 1) >>> 4))
        dst += b64.charAt(((utf8str.charCodeAt(i + 1) & 15) << 2) | (utf8str.charCodeAt(i + 2) >>> 6))
        dst += b64.charAt(utf8str.charCodeAt(i + 2) & 63)
    }

    if (len % 3 == 2) {
        dst += b64.charAt(utf8str.charCodeAt(i) >>> 2)
        dst += b64.charAt(((utf8str.charCodeAt(i) & 3) << 4) | (utf8str.charCodeAt(i + 1) >>> 4))
        dst += b64.charAt(((utf8str.charCodeAt(i + 1) & 15) << 2))
    }
    else if (len % 3 == 1) {
        dst += b64.charAt(utf8str.charCodeAt(i) >>> 2)
        dst += b64.charAt(((utf8str.charCodeAt(i) & 3) << 4))
    }

    return dst
}

const headers = JSON.stringify(headers)
const payload = JSON.stringify(payload)
const token = `${base64Encode(headers)}.${base64Encode(payload)}`
console.log(token)
}