An implementation of JSON Web Tokens.
This was developed against draft-ietf-oauth-json-web-token-08. It makes use of node-jws
Install
$ npm install jsonwebtoken
Usage
jwt.sign(payload, secretOrPrivateKey, options, callback)
(异步)使用 err 或 JWT 调用回调
(同步)返回 JsonWebToken 字符串
payload必须是一个object,buffer或string。exp只有当payload是 object字面量时才可以设置secretOrPrivateKey包含HMAC算法的密钥 或RSA和ECDSA的PEM编码私钥的string或bufferoptions:algorithm加密算法 (默认:HS256)expiresIn过期时间。以秒表示或描述时间跨度 zeit/ms 的字符串。如60,"2 days","10h","7d"notBefore以秒表示或描述时间跨度 zeit/ms 的字符串。如60,"2days","10h","7d"audience接收方issuer签发方jwtidsubjectnoTimestampheaderkeyid
####注意
- 如果
payload不是 Buffer或String,它将被JSON.stringify()强制转换为字符串。 - 在
expiresIn,notBefore,audience,subject,issuer没有默认值时。可以直接在payload中用exp,nbf,aud,sub和iss分别表示,但是不能在这两个地方同时设置。 - 请记住
exp,nbf,iat是NumericDate类型。 - 生成的jwts通常会包含一个
iat值除非指定了noTimestamp。如果iat插入到payload中,它将被用来代替真正的时间戳来计算其他东西,例如options.expiresIn给定一个exp这样的时间间隔。 issuer和audience在签发时缩写为iss和aud,否则在"jsonwebtoken": "^8.0.1"的版本中使用jwt.verify校验时无法通过
####示例
// sign with default (HMAC SHA256)
var jwt = require('jsonwebtoken');
var token = jwt.sign({ foo: 'bar' }, 'shhhhh');
//backdate a jwt 30 seconds
var older_token = jwt.sign({ foo: 'bar', iat: Math.floor(Date.now() / 1000) - 30 }, 'shhhhh');
// sign with RSA SHA256
var cert = fs.readFileSync('private.key'); // get private key
var token = jwt.sign({ foo: 'bar' }, cert, { algorithm: 'RS256'});
// sign asynchronously
jwt.sign({ foo: 'bar' }, cert, { algorithm: 'RS256' }, function(err, token) {
console.log(token);
});
Token 到期 (exp claim)
exp 包含自纪元以来的秒数。
有效时间为1小时的Token:
jwt.sign({
exp: Math.floor(Date.now() / 1000) + (60 * 60),
data: 'foobar'
}, 'secret');
另一种方法:
jwt.sign({
data: 'foobar'
}, 'secret', { expiresIn: 60 * 60 });
// or even better:
jwt.sign({
data: 'foobar'
}, 'secret', { expiresIn: '1h' });
jwt.verify(token, secretOrPublicKey, options, callback)
(异步)如果 token 是有效的,可选值 expiration, audience 或 issuer 是有效的,则解码成功并回调。否则,错误回调。
(同步)token 有效时返回 expiration, audience 或 issuer。否则抛出错误。
tokenJsonWebToken 字符串secretOrPublicKeyHMAC算法生成的String或Buffer, 或RSA和ECDSA编码生成的私钥文件
如果要使用 base64 的加密数据,则使用
Buffer.from(secret, 'base64')解析成原始的字符串传入
optionsalgorithms加密算法,例如["HS256", "HS384"]audience接收方issuer签发方,可选。值为String或ArrayignoreExpiration如果为true不要验证令牌的到期时间ignoreNotBeforesubjectclockTolerance检查NBF和exp时允许的误差时间(秒数),以应对不同服务器之间的时钟差异maxAge: 令牌的最大允许有效期。以秒表示或描述时间跨度 zeit/ms 的字符串。如1000,"2 days","10h","7d"clockTimestamp
// 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
});
jwt.decode(token , options)
(同步) 返回解码后的 payload ,但不验证签名是否有效。
tokenis the JsonWebToken stringoptions:jsonforce JSON.parse on the payload even if the header doesn't contain"typ":"JWT".complete解码后是否包含payload和header
示例
// 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
TokenExpiredError
令牌过期的错误
Error 对象:
- name: 'TokenExpiredError'
- message: 'jwt expired'
- expiredAt: ExpDate
jwt.verify(token, 'shhhhh', function(err, decoded) {
if (err) {
/*
err = {
name: 'TokenExpiredError',
message: 'jwt expired',
expiredAt: 1408621000
}
*/
}
});
JsonWebTokenError
Error 对象:
- name: 'JsonWebTokenError'
- message:
- 'jwt malformed'
- 'jwt signature is required'
- 'invalid signature'
- 'jwt audience invalid. expected: OPTIONS AUDIENCE'
- 'jwt issuer invalid. expected: OPTIONS ISSUER'
- 'jwt id invalid. expected: OPTIONS JWT ID'
- 'jwt subject invalid. expected: OPTIONS SUBJECT'
jwt.verify(token, 'shhhhh', function(err, decoded) {
if (err) {
/*
err = {
name: 'JsonWebTokenError',
message: 'jwt malformed'
}
*/
}
});
支持的算法
支持算法数组。目前支持以下算法。
| 参数值 | 算法 |
|---|---|
| HS256 | HMAC using SHA-256 hash algorithm |
| HS384 | HMAC using SHA-384 hash algorithm |
| HS512 | HMAC using SHA-512 hash algorithm |
| RS256 | RSASSA using SHA-256 hash algorithm |
| RS384 | RSASSA using SHA-384 hash algorithm |
| RS512 | RSASSA using SHA-512 hash algorithm |
| 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 |