jsonwebtoken - npm (npmjs.com)
jsonwebtoken
An implementation of JSON Web Tokens.
一个JSON Web Tokens(JSON 网络令牌)的实现。
This was developed against draft-ietf-oauth-json-web-token-08. It makes use of node-jws
这是基于draft-ietf-oauth-json-web-token-08草案开发的。它使用了[node-jws]((一个Node.js的JSON Web Signature库))。
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.
(异步)如果提供了回调函数,则回调函数会被调用,并传入错误对象或JWT。
(Synchronous) Returns the JsonWebToken as string
(同步)返回JsonWebToken的字符串形式
payload could be an object literal, buffer or string representing valid JSON.
payload可以是一个对象字面量、缓冲区或表示有效JSON的字符串。
Please *note* that
expor any other claim is only set if the payload is an object literal. Buffer or string payloads are not checked for JSON validity.请注意,只有当
payload是一个对象字面量时,exp或其他任何声明才会被设置。缓冲区或字符串形式的payload不会被检查其JSON有效性。
If
payloadis not a buffer or a string, it will be coerced into a string usingJSON.stringify.如果
payload不是缓冲区或字符串,它将被JSON.stringify强制转换为字符串。
secretOrPrivateKey is a string (utf-8 encoded), buffer, object, or KeyObject containing either the secret for HMAC algorithms or the PEM encoded private key for RSA and ECDSA. 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. When signing with RSA algorithms the minimum modulus length is 2048 except when the allowInsecureKeySizes option is set to true. Private keys below this size will be rejected with an error.
secretOrPrivateKey是一个字符串(utf-8编码)、缓冲区、对象或包含HMAC算法的秘密或RSA和ECDSA的PEM编码私钥的KeyObject。如果私钥带有密码短语,可以使用一个对象{ key, passphrase }(基于crypto文档),在这种情况下,请确保传递algorithm选项。当使用RSA算法签名时,最小模数长度为2048,除非将allowInsecureKeySizes选项设置为true。小于此大小的私钥将被拒绝并报错。
options:
-
algorithm(default:HS256) -
expiresIn: expressed in seconds or a string describing a time span
:以秒为单位表示或描述时间跨度的字符串
vercel/ms
.(使用vercel/ms库)
Eg:
60,"2 days","10h","7d". A numeric value is interpreted as a seconds count. If you use a string be sure you provide the time units (days, hours, etc), otherwise milliseconds unit is used by default ("120"is equal to"120ms").例如:
60、"2 days"、"10h"、"7d"。数值被解释为秒数。如果使用字符串,请确保提供时间单位(天、小时等),否则默认使用毫秒单位("120"等于"120ms")。 -
notBefore: expressed in seconds or a string describing a time span
:以秒为单位表示或描述时间跨度的字符串
vercel/ms
.(使用vercel/ms库)
Eg:
60,"2 days","10h","7d". A numeric value is interpreted as a seconds count. If you use a string be sure you provide the time units (days, hours, etc), otherwise milliseconds unit is used by default ("120"is equal to"120ms").例如:
60、"2 days"、"10h"、"7d"。数值被解释为秒数。如果使用字符串,请确保提供时间单位(天、小时等),否则默认使用毫秒单位("120"等于"120ms")。 -
audience -
issuer -
jwtid -
subject -
noTimestamp -
header -
keyid -
mutatePayload: if true, the sign function will modify the payload object directly. This is useful if you need a raw reference to the payload after claims have been applied to it but before it has been encoded into a token. -
allowInsecureKeySizes: if true allows private keys with a modulus below 2048 to be used for RSA -
allowInvalidAsymmetricKeyTypes: if true, allows asymmetric keys which do not match the specified algorithm. This option is intended only for backwards compatability and should be avoided. -
audience(受众) -
issuer(签发者) -
jwtid(JWT ID) -
subject(主题) -
noTimestamp(无时间戳) -
header(头部) -
keyid(密钥ID) -
mutatePayload:如果为true,sign函数将直接修改payload对象。如果你需要在声明被应用到payload上之后但在它被编码成令牌之前获得对payload的原始引用,这将非常有用。 -
allowInsecureKeySizes:如果为true,则允许模数小于2048的私钥用于RSA。 -
allowInvalidAsymmetricKeyTypes:如果为true,则允许与指定算法不匹配的非对称密钥。此选项仅用于向后兼容,应避免使用。
There are no default values for
expiresIn,notBefore,audience,subject,issuer. These claims can also be provided in the payload directly withexp,nbf,aud,subandissrespectively, but you *can’t* include in both places.
expiresIn、notBefore、audience、subject、issuer没有默认值。这些声明也可以直接在payload中以exp、nbf、aud、sub和iss的形式提供,但不能同时在两个地方包含。
Remember that exp, nbf and iat are NumericDate, see related Token Expiration (exp claim)
请记住,exp、nbf和iat是NumericDate,请参阅相关的Token Expiration(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. 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.
除非指定了noTimestamp,否则生成的JWT将默认包含iat(签发时间)声明。如果iat被插入到payload中,它将用于计算其他内容,如给定options.expiresIn时间跨度的exp,而不是使用实际的时间戳。
Synchronous Sign with default (HMAC SHA256)
同步签名使用默认(HMAC SHA256)
var jwt = require('jsonwebtoken');
var token = jwt.sign({ foo: 'bar' }, 'shhhhh');
Synchronous Sign with RSA SHA256
使用RSA SHA256进行同步签名
// 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. The expiration is represented as a NumericDate:
JWT标准定义了一个exp声明来表示过期时间。过期时间以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. 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. See RFC 3339 [RFC3339] for details regarding date/times in general and UTC in particular.
一个JSON数值,表示从1970-01-01T00:00:00Z UTC到指定的UTC日期/时间的秒数,忽略闰秒。这相当于IEEE Std 1003.1,2013年版[POSIX.1]中定义的“自纪元以来的秒数”(Seconds Since the Epoch),其中每天恰好为86400秒,但除此之外也可以表示非整数值。有关日期/时间和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
token 是 JsonWebToken 字符串。
secretOrPublicKey is a string (utf-8 encoded), buffer, or KeyObject containing either the secret for HMAC algorithms, or the PEM encoded public key for RSA and ECDSA. If jwt.verify is called asynchronous, secretOrPublicKey can be a function that should fetch the secret or public key. See below for a detailed example
secretOrPublicKey 是一个字符串(utf-8 编码)、缓冲区或 KeyObject,包含 HMAC 算法的密钥,或者 RSA 和 ECDSA 的 PEM 编码公钥。如果 jwt.verify 是异步调用的,那么 secretOrPublicKey 可以是一个函数,该函数应获取密钥或公钥。下面是一个详细的示例。
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
-
algorithms-
: List of strings with the names of the allowed algorithms. For instance,
- 允许使用的算法名称的字符串列表。例如,
["HS256", "HS384"].
If not specified a defaults will be used based on the type of key provided
如果未指定,则将基于所提供的密钥类型使用默认值。
- secret - [‘HS256’, ‘HS384’, ‘HS512’]
- rsa - [‘RS256’, ‘RS384’, ‘RS512’]
- ec - [‘ES256’, ‘ES384’, ‘ES512’]
- default - [‘RS256’, ‘RS384’, ‘RS512’]
-
audience: if you want to check audience (
aud), provide a value here. The audience can be checked against a string, a regular expression or a list of strings and/or regular expressions.
:如果您想检查受众(
aud),请在此处提供一个值。受众可以与字符串、正则表达式或字符串和/或正则表达式的列表进行匹配。Eg:
"urn:foo",/urn:f[o]{2}/,[/urn:f[o]{2}/, "urn:bar"] -
complete: return an object with the decoded{ payload, header, signature }instead of only the usual content of the payload. -
issuer(optional): string or array of strings of valid values for theissfield. -
jwtid(optional): if you want to check JWT ID (jti), provide a string value here. -
ignoreExpiration: iftruedo not validate the expiration of the token. -
ignoreNotBefore… -
subject: if you want to check subject (sub), provide a value here -
clockTolerance: number of seconds to tolerate when checking thenbfandexpclaims, to deal with small clock differences among different servers -
maxAge: the maximum allowed age for tokens to still be valid. It is expressed in seconds or a string describing a time span
-
complete:返回一个包含解码后的{ payload, header, signature }的对象,而不仅仅是通常的有效载荷内容。 -
issuer(可选):iss字段的有效值的字符串或字符串数组。 -
jwtid(可选):如果您想检查JWT ID(jti),请在此处提供一个字符串值。 -
ignoreExpiration:如果为true,则不验证令牌的过期时间。 -
ignoreNotBefore…(此处省略了具体说明) -
subject:如果您想检查主题(sub),请在此处提供一个值。 -
clockTolerance:在检查nbf和exp声明时容忍的秒数,以处理不同服务器之间的小时钟差异。 -
maxAge:令牌仍然有效的最大允许年龄。它以秒为单位表示,或者是一个描述时间跨度的字符串。
vercel/ms
.使用vercel/ms库进行时间解析。
Eg:
1000,"2 days","10h","7d". A numeric value is interpreted as a seconds count. If you use a string be sure you provide the time units (days, hours, etc), otherwise milliseconds unit is used by default ("120"is equal to"120ms").例如:
1000,"2 days","10h","7d"。数值被解释为秒数。如果您使用字符串,请确保提供时间单位(天、小时等),否则默认使用毫秒单位("120"等于"120ms")。 -
-
clockTimestamp: the time in seconds that should be used as the current time for all necessary comparisons. -
clockTimestamp:用于所有必要比较的当前时间,以秒为单位的时间戳。 -
nonce: if you want to check nonce claim, provide a string value here. It is used on Open ID for the ID Tokens. (Open ID implementation notes)
-
nonce:如果您想检查nonce声明,请在此处提供一个字符串值。它在OpenID中用于ID令牌。(OpenID实现说明) -
allowInvalidAsymmetricKeyTypes: if true, allows asymmetric keys which do not match the specified algorithm. This option is intended only for backwards compatability and should be avoided.
-
allowInvalidAsymmetricKeyTypes:如果为true,则允许与指定算法不匹配的非对称密钥。此选项仅用于向后兼容,应避免使用。
// 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
});
Errors & Codes
Possible thrown errors during verification. Error is the first argument of the verification callback.
在验证过程中可能抛出的错误。错误是验证回调的第一个参数。
TokenExpiredError
Thrown error if the token is expired.
如果令牌已过期,则抛出此错误。
Error object: 错误对象:
-
name: ‘TokenExpiredError’
-
message: ‘jwt expired’
-
message: ‘jwt已过期’
-
expiredAt: [ExpDate]
-
expiredAt: [过期日期]
jwt.verify(token, 'shhhhh', function(err, decoded) {
if (err) {
/*
err = {
name: 'TokenExpiredError',
message: 'jwt expired',
expiredAt: 1408621000
}
*/
}
});
JsonWebTokenError
Error object: 错误对象:
- name: ‘JsonWebTokenError’
- message:
- ‘invalid token’ - the header or payload could not be parsed
- ‘无效令牌’ - 无法解析头部或有效载荷
- ‘jwt malformed’ - the token does not have three components (delimited by a
.) - ‘jwt格式错误’ - 令牌没有三个部分(由
.分隔) - ‘jwt signature is required’
- ‘需要jwt签名’
- ‘invalid signature’
- ‘签名无效’
- ‘jwt audience invalid. expected: [OPTIONS AUDIENCE]’
- ‘jwt受众无效。预期:[选项中的受众]’
- ‘jwt issuer invalid. expected: [OPTIONS ISSUER]’
- ‘jwt发行人无效。预期:[选项中的发行人]’
- ‘jwt id invalid. expected: [OPTIONS JWT ID]’
- ‘jwt ID无效。预期:[选项中的JWT ID]’
- ‘jwt subject invalid. expected: [OPTIONS SUBJECT]’
- ‘jwt主题无效。预期:[选项中的主题]’
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(Not Before)声明之前,则抛出此错误。
Error object: 错误对象:
- name: ‘NotBeforeError’
- message: ‘jwt not active’
- message: ‘jwt未激活’
- date: 2018-10-04T16:10:44.000Z
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 |
|---|---|
| HS256 | HMAC using SHA-256 hash algorithm |
| HS384 | HMAC using SHA-384 hash algorithm |
| HS512 | HMAC using SHA-512 hash algorithm |
| RS256 | RSASSA-PKCS1-v1_5 using SHA-256 hash algorithm |
| RS384 | RSASSA-PKCS1-v1_5 using SHA-384 hash algorithm |
| RS512 | RSASSA-PKCS1-v1_5 using SHA-512 hash algorithm |
| 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 |
支持的算法
支持的算法数组。目前支持以下算法:
| alg 参数值 | 数字签名或MAC算法 |
|---|---|
| HS256 | 使用SHA-256哈希算法的HMAC |
| HS384 | 使用SHA-384哈希算法的HMAC |
| HS512 | 使用SHA-512哈希算法的HMAC |
| RS256 | 使用SHA-256哈希算法的RSASSA-PKCS1-v1_5 |
| RS384 | 使用SHA-384哈希算法的RSASSA-PKCS1-v1_5 |
| RS512 | 使用SHA-512哈希算法的RSASSA-PKCS1-v1_5 |
| PS256 | 使用SHA-256哈希算法的RSASSA-PSS(仅支持node ^6.12.0或>=8.0.0) |
| PS384 | 使用SHA-384哈希算法的RSASSA-PSS(仅支持node ^6.12.0或>=8.0.0) |
| PS512 | 使用SHA-512哈希算法的RSASSA-PSS(仅支持node ^6.12.0或>=8.0.0) |
| ES256 | 使用P-256曲线和SHA-256哈希算法的ECDSA |
| ES384 | 使用P-384曲线和SHA-384哈希算法的ECDSA |
| ES512 | 使用P-521曲线和SHA-512哈希算法的ECDSA |
| none | 不包含数字签名或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.
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.
刷新JWT
首先,我们建议您仔细考虑自动刷新JWT是否会在您的系统中引入任何漏洞。
我们不愿意将此作为库的一部分,但是您可以查看这个示例来了解如何实现这一点。除了这个示例之外,还有一个问题和一个拉取请求,您可以查看它们以获取关于这个话题的更多知识。
2010

被折叠的 条评论
为什么被折叠?



