自定义 JWT Payload

FeatusJS的 Auk 版本包括一个强大的新的 认证 建立在 PassportJS 之上. 新插件非常灵活, 允许您自定义几乎所有内容.最新版本中添加的一项功能是使用挂钩自定义 JWT payload 的功能.让我们来看看这意味着什么,如何使它工作,并了解使用它可能遇到的潜在陷阱.

JWT Payload

如果您阅读以下资源 JSON Web Tokens 是如何工作的, 您将知道JWT是一个可以包含有效负载的编码字符串.有关快速示例, 请查看 jwt.io 上的调试器. jwt.io. 上的紫色部分是 payload . 您还会注意到可以在有效负载中放置任意数据. payload 数据被编码为JWT字符串的一部分.

默认的JWT payload 包含以下声明:

const decode = require('jwt-decode')
// Retrieve the token from wherever you've stored it.
const jwt = window.localStorage.getItem('feathers-jwt')
const payload = decode(jwt)

payload === {
  aud: 'https://yourdomain.com', // audience
  exp: 23852348347, // expires at time
  iat: 23852132232, // issued at time
  iss: 'feathers', // issuer
  sub: 'anonymous', // subject
  userId: 1 // the user's id
}

请注意, payload 编码为, 未加密. 这是一个重要的区别.这意味着您要小心存储在JWT payload 中的内容.

使用挂钩自定义Payload

身份验证服务在JWT payload 的钩子上下文中使用 params.payload 对象.这意味着您可以通过在 authenticate 钩子之后添加一个前挂钩来自定义JWT.

app.service('authentication').hooks({
  before: {
    create: [
      authentication.hooks.authenticate(config.strategies),

      // This hook adds the `test` attribute to the JWT payload by
      // modifying params.payload.
      context => {
        // make sure params.payload exists
        context.params.payload = context.params.payload || {}
        // merge in a `test` property
        Object.assign(context.params.payload, {test: 'test'})
      }
    ],
    remove: [
      authentication.hooks.authenticate('jwt')
    ]
  }
})

现在 payload 将包含 test 属性:

const decode = require('jwt-decode')
// Retrieve the token from wherever you've stored it.
const jwt = window.localStorage.getItem('feathers-jwt')
const payload = decode(jwt)

payload === {
  aud: 'https://yourdomain.com',
  exp: 23852348347,
  iat: 23852132232,
  iss: 'feathers',
  sub: 'anonymous',
  userId: 1
  test: 'test' // Here's the new claim we just added
}

注解

payload 不会自动解码并在挂钩中可用,因此需要您在应用中实现此功能.使用 jwt-decode 是一个简单的解决方案,可以根据需要放入钩子中.

重要的安全信息

在向JWT payload 添加数据时,令牌大小会变大.试试看 jwt.io 来亲自看看.在自定义 payload 时,请记住一个重要的安全问题.此问题涉及用于对令牌进行签名的默认 HS256 算法.

对于 HS256,秘密长度(必须至少为256位)与编码令牌的长度(随 payload 而变化)之间存在关系.更大的秘密到 payload 比(因此秘密大于JWT)将导致更安全的JWT.这也意味着保持秘密大小相同并增加 payload 大小实际上会使您的JWT相对不太安全.

默认情况下,Feathers生成器会创建一个2048位的密钥,因此可以在JWT payload 中添加少量允许空间来放置其他属性.保持秘密到 payload 长度比尽可能高以避免暴力攻击非常重要.在暴力攻击中,攻击者试图通过一遍又一遍地猜测秘密来检索秘密,直到它正确为止.如果您的秘密被泄露,他们将能够创建他们希望的任何 payload 的签名JWT.简而言之,请谨慎对待JWT payload 中的内容.

最后,请记住,生成器创建的秘密仅用于开发目的.你永远不想把你的 生产 秘密检查到你的版本控制系统(Git等).最好将生产秘密放在环境变量中,并在应用程序配置中引用它.