jsonwebtoken

Build Dependency
Build Status Dependency Status

An implementation of JSON Web Tokens.JSON Web令牌的实现。

This was developed against draft-ietf-oauth-json-web-token-08. 这是根据草案draft-ietf-oauth-json-web-token-08开发的。It makes use of node-jws它利用了node-jws

Install安装

$ npm install jsonwebtoken

Migration notes迁移说明

Usage用法

jwt.sign(payload, secretOrPrivateKey, [options, callback])

(Asynchronous) If a callback is supplied, the callback is called with the err or the JWT.如果提供了回调,则使用err或JWT调用回调。

(Synchronous) Returns the JsonWebToken as string以字符串形式返回JsonWebToken

payload could be an object literal, buffer or string representing valid JSON.可以是表示有效JSON的对象文字、缓冲区或字符串。

Please note that exp or any other claim is only set if the payload is an object literal. 请注意,exp或任何其他声明仅在有效负载为对象文字时设置。Buffer or string payloads are not checked for JSON validity.未检查缓冲区或字符串有效负载的JSON有效性。

If payload is not a buffer or a string, it will be coerced into a string using JSON.stringify.如果payload不是缓冲区或字符串,则将使用JSON.stringify将其强制转换为字符串。

secretOrPrivateKey is a string, buffer, or object containing either the secret for HMAC algorithms or the PEM encoded private key for RSA and ECDSA. 是一个字符串、缓冲区或对象,包含HMAC算法的密钥或RSA和ECDSA的PEM编码私钥。In case of a private key with passphrase an object { key, passphrase } can be used (based on crypto documentation), in this case be sure you pass the algorithm option.对于带有密码短语的私钥,可以使用对象{ key, passphrase }(基于加密文档),在这种情况下,请确保传递算法选项。

options:

There are no default values for expiresIn, notBefore, audience, subject, issuer. expiresInnotBeforeaudiencesubjectissuer没有默认值。These claims can also be provided in the payload directly with exp, nbf, aud, sub and iss respectively, but you can't include in both places.这些声明也可以分别通过expnbfaudsubiss直接在有效载荷中提供,但不能同时包含在这两个位置。

Remember that exp, nbf and iat are NumericDate, see related Token Expiration (exp claim)请记住,expnbfiatNumericDate,请参阅相关令牌到期(exp索赔)

The header can be customized via the options.header object.可以通过options.header对象自定义标题。

Generated jwts will include an iat (issued at) claim by default unless noTimestamp is specified. 除非指定了noTimestamp,否则生成的JWT将默认包括iat(在发出时)索赔。If iat is inserted in the payload, it will be used instead of the real timestamp for calculating other things like exp given a timespan in options.expiresIn.如果在有效负载中插入iat,则在options.expiresIn中给定时间跨度时,将使用iat而不是实际时间戳来计算exp等其他内容。

Synchronous Sign with default (HMAC SHA256)带默认值的同步签名(HMAC SHA256)

var jwt = require('jsonwebtoken');
var token = jwt.sign({ foo: 'bar' }, 'shhhhh');

Synchronous Sign with RSA SHA256rsasa256同步签名

// sign with RSA SHA256
var privateKey = fs.readFileSync('private.key');
var token = jwt.sign({ foo: 'bar' }, privateKey, { algorithm: 'RS256' });

Sign asynchronously异步签名

jwt.sign({ foo: 'bar' }, privateKey, { algorithm: 'RS256' }, function(err, token) {
  console.log(token);
});

Backdate a jwt 30 seconds回溯jwt 30秒

var older_token = jwt.sign({ foo: 'bar', iat: Math.floor(Date.now() / 1000) - 30 }, 'shhhhh');

Token Expiration (exp claim)

The standard for JWT defines an exp claim for expiration. JWT的标准定义了exp到期索赔。The expiration is represented as a NumericDate:到期日期表示为数字日期

A JSON numeric value representing the number of seconds from 1970-01-01T00:00:00Z UTC until the specified UTC date/time, ignoring leap seconds. JSON数值,表示从UTC 1970-01-01T00:00:00Z到指定UTC日期/时间的秒数,忽略闰秒。This is equivalent to the IEEE Std 1003.1, 2013 Edition [POSIX.1] definition "Seconds Since the Epoch", in which each day is accounted for by exactly 86400 seconds, other than that non-integer values can be represented. 这相当于IEEE Std 1003.1,2013版[POSIX.1]的定义“从纪元算起的秒数”,在该定义中,除了可以表示非整数值外,每天的秒数正好为86400秒。See RFC 3339 [RFC3339] for details regarding date/times in general and UTC in particular.有关一般日期/时间,特别是UTC的详细信息,请参阅RFC 3339[RFC3339]。

This means that the exp field should contain the number of seconds since the epoch.这意味着exp字段应包含自历元以来的秒数。

Signing a token with 1 hour of expiration:签署到期时间为1小时的令牌:

jwt.sign({
  exp: Math.floor(Date.now() / 1000) + (60 * 60),
  data: 'foobar'
}, 'secret');

Another way to generate a token like this with this library is:使用此库生成这样的令牌的另一种方法是:

jwt.sign({
  data: 'foobar'
}, 'secret', { expiresIn: 60 * 60 });

//or even better:

jwt.sign({
  data: 'foobar'
}, 'secret', { expiresIn: '1h' });

jwt.verify(token, secretOrPublicKey, [options, callback])

(Asynchronous) If a callback is supplied, function acts asynchronously. (异步)如果提供了回调,则函数将异步运行。The callback is called with the decoded payload if the signature is valid and optional expiration, audience, or issuer are valid. If not, it will be called with the error.如果签名有效且可选的过期、访问群体或颁发者有效,则使用解码的有效负载调用回调。如果不是,则调用它时会出现错误。

(Synchronous) If a callback is not supplied, function acts synchronously. (同步)如果未提供回调,函数将同步运行。Returns the payload decoded if the signature is valid and optional expiration, audience, or issuer are valid. If not, it will throw the error.如果签名有效且可选过期、访问群体或颁发者有效,则返回已解码的有效负载。如果不是,它将抛出错误。

Warning: When the token comes from an untrusted source (e.g. user input or external requests), the returned decoded payload should be treated like any other user input; please make sure to sanitize and only work with properties that are expected当令牌来自不受信任的来源(例如用户输入或外部请求)时,返回的解码有效负载应与任何其他用户输入一样处理;请确保进行清理,并且只处理预期的属性

token is the JsonWebToken string是JsonWebToken字符串

secretOrPublicKey is a string or buffer containing either the secret for HMAC algorithms, or the PEM encoded public key for RSA and ECDSA.是一个字符串或缓冲区,其中包含HMAC算法的密钥,或包含RSA和ECDSA的PEM编码公钥。If jwt.verify is called asynchronous, secretOrPublicKey can be a function that should fetch the secret or public key. 如果jwt.verify以异步的方式调用,那么secretOrPublicKey可以是一个函数,它应该获取秘密或公钥。See below for a detailed example请参见下面的详细示例

As mentioned in this comment, there are other libraries that expect base64 encoded secrets (random bytes encoded using base64), if that is your case you can pass Buffer.from(secret, 'base64'), by doing this the secret will be decoded using base64 and the token verification will use the original random bytes.本评论中所述,还有其他库需要base64编码的机密(使用base64编码的随机字节),如果您是这样的话,您可以传入Buffer.from(secret, 'base64'),通过这样做,密钥将使用base64解码,令牌验证将使用原始随机字节。

options

// verify a token symmetric - synchronous
var decoded = jwt.verify(token, 'shhhhh');
console.log(decoded.foo) // bar

// verify a token symmetric
jwt.verify(token, 'shhhhh', function(err, decoded) {
  console.log(decoded.foo) // bar
});

// invalid token - synchronous
try {
  var decoded = jwt.verify(token, 'wrong-secret');
} catch(err) {
  // err
}

// invalid token
jwt.verify(token, 'wrong-secret', function(err, decoded) {
  // err
  // decoded undefined
});

// verify a token asymmetric
var cert = fs.readFileSync('public.pem');  // get public key
jwt.verify(token, cert, function(err, decoded) {
  console.log(decoded.foo) // bar
});

// verify audience
var cert = fs.readFileSync('public.pem');  // get public key
jwt.verify(token, cert, { audience: 'urn:foo' }, function(err, decoded) {
  // if audience mismatch, err == invalid audience
});

// verify issuer
var cert = fs.readFileSync('public.pem');  // get public key
jwt.verify(token, cert, { audience: 'urn:foo', issuer: 'urn:issuer' }, function(err, decoded) {
  // if issuer mismatch, err == invalid issuer
});

// verify jwt id
var cert = fs.readFileSync('public.pem');  // get public key
jwt.verify(token, cert, { audience: 'urn:foo', issuer: 'urn:issuer', jwtid: 'jwtid' }, function(err, decoded) {
  // if jwt id mismatch, err == invalid jwt id
});

// verify subject
var cert = fs.readFileSync('public.pem');  // get public key
jwt.verify(token, cert, { audience: 'urn:foo', issuer: 'urn:issuer', jwtid: 'jwtid', subject: 'subject' }, function(err, decoded) {
  // if subject mismatch, err == invalid subject
});

// alg mismatch
var cert = fs.readFileSync('public.pem'); // get public key
jwt.verify(token, cert, { algorithms: ['RS256'] }, function (err, payload) {
  // if token alg != RS256,  err == invalid signature
});

// Verify using getKey callback
// Example uses https://github.com/auth0/node-jwks-rsa as a way to fetch the keys.
var jwksClient = require('jwks-rsa');
var client = jwksClient({
  jwksUri: 'https://sandrino.auth0.com/.well-known/jwks.json'
});
function getKey(header, callback){
  client.getSigningKey(header.kid, function(err, key) {
    var signingKey = key.publicKey || key.rsaPublicKey;
    callback(null, signingKey);
  });
}

jwt.verify(token, getKey, options, function(err, decoded) {
  console.log(decoded.foo) // bar
});
Need to peek into a JWT without verifying it? (Click to expand)需要偷看JWT而不验证它吗?(单击展开)

jwt.decode(token [, options])

(Synchronous) Returns the decoded payload without verifying if the signature is valid.(同步)返回解码的有效负载,而不验证签名是否有效。

Warning: This will not verify whether the signature is valid. 这将不会验证签名是否有效。You should not use this for untrusted messages. 您不应将其用于不受信任的邮件。You most likely want to use jwt.verify instead.您很可能希望改用jwt.verify

Warning: When the token comes from an untrusted source (e.g. user input or external request), the returned decoded payload should be treated like any other user input; please make sure to sanitize and only work with properties that are expected当令牌来自不受信任的来源(例如用户输入或外部请求)时,返回的解码有效负载应与任何其他用户输入一样处理;请确保进行清理,并且只处理预期的属性

token is the JsonWebToken string是JsonWebToken字符串

options:

Example例子

// get the decoded payload ignoring signature, no secretOrPrivateKey needed
var decoded = jwt.decode(token);

// get the decoded payload and header
var decoded = jwt.decode(token, {complete: true});
console.log(decoded.header);
console.log(decoded.payload)

Errors & Codes

Possible thrown errors during verification.验证期间可能抛出错误。Error is the first argument of the verification callback.Error是验证回调的第一个参数。

TokenExpiredError

Thrown error if the token is expired.如果令牌过期,则引发错误。

Error object:错误对象:

jwt.verify(token, 'shhhhh', function(err, decoded) {
  if (err) {
    /*
      err = {
        name: 'TokenExpiredError',
        message: 'jwt expired',
        expiredAt: 1408621000
      }
    */
  }
});

JsonWebTokenError

Error object:

jwt.verify(token, 'shhhhh', function(err, decoded) {
  if (err) {
    /*
      err = {
        name: 'JsonWebTokenError',
        message: 'jwt malformed'
      }
    */
  }
});

NotBeforeError

Thrown if current time is before the nbf claim.如果当前时间在nbf声明之前,则引发。

Error object:

jwt.verify(token, 'shhhhh', function(err, decoded) {
  if (err) {
    /*
      err = {
        name: 'NotBeforeError',
        message: 'jwt not active',
        date: 2018-10-04T16:10:44.000Z
      }
    */
  }
});

Algorithms supported支持的算法

Array of supported algorithms. The following algorithms are currently supported.支持的算法数组。目前支持以下算法。

alg Parameter Value Digital Signature or MAC Algorithm数字签名或MAC算法
HS256 HMAC using SHA-256 hash algorithm使用SHA-256哈希算法的HMAC
HS384 HMAC using SHA-384 hash algorithm使用SHA-384哈希算法的HMAC
HS512 HMAC using SHA-512 hash algorithm使用SHA-512哈希算法的HMAC
RS256 RSASSA-PKCS1-v1_5 using SHA-256 hash algorithm使用SHA-256哈希算法的RSASSA-PKCS1-v1_5
RS384 RSASSA-PKCS1-v1_5 using SHA-384 hash algorithm使用SHA-384哈希算法的RSASSA-PKCS1-v1_5
RS512 RSASSA-PKCS1-v1_5 using SHA-512 hash algorithm使用SHA-512哈希算法的RSASSA-PKCS1-v1_5
PS256 RSASSA-PSS using SHA-256 hash algorithm (only node ^6.12.0 OR >=8.0.0)
PS384 RSASSA-PSS using SHA-384 hash algorithm (only node ^6.12.0 OR >=8.0.0)
PS512 RSASSA-PSS using SHA-512 hash algorithm (only node ^6.12.0 OR >=8.0.0)
ES256 ECDSA using P-256 curve and SHA-256 hash algorithm
ES384 ECDSA using P-384 curve and SHA-384 hash algorithm
ES512 ECDSA using P-521 curve and SHA-512 hash algorithm
none No digital signature or MAC value included不包括数字签名或MAC值

Refreshing JWTs

First of all, we recommend you to think carefully if auto-refreshing a JWT will not introduce any vulnerability in your system.首先,我们建议您仔细考虑自动刷新JWT是否不会在您的系统中引入任何漏洞。

We are not comfortable including this as part of the library, however, you can take a look at this example to show how this could be accomplished.我们不愿意将此作为库的一部分,但是,您可以查看此示例来说明如何实现此功能。 Apart from that example there are an issue and a pull request to get more knowledge about this topic.除了这个例子之外,还有一个问题和一个获取更多关于这个主题的知识的请求

TODO

Issue Reporting问题报告

If you have found a bug or if you have a feature request, please report them at this repository issues section. 如果您发现了一个bug或者有一个功能请求,请在这个存储库问题部分报告它们。Please do not report security vulnerabilities on the public GitHub issue tracker. 请不要在公共GitHub问题跟踪器上报告安全漏洞。The Responsible Disclosure Program details the procedure for disclosing security issues.责任披露计划详细说明了披露安全问题的程序。

Author

Auth0

License

This project is licensed under the MIT license. See the LICENSE file for more info.这个项目是根据MIT的许可证授权的。有关更多信息,请参阅许可证文件。